首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何跳过YASM中的单词(8086)

如何跳过YASM中的单词(8086)
EN

Stack Overflow用户
提问于 2022-11-17 16:24:17
回答 2查看 65关注 0票数 1

我一直在做这个项目。主要目的是计算有多少单词不包含字母'B‘或'C’。给定文件有0;1000行。每一行包含6列。

前两列包含1;20个字符的字符串。字符可以是字母、数字和空格。

3-5列包含范围为- 100;100的整数。第6列包含范围内的实数- 9.99;9.99,小数点后只有两位数。

每一段我用分号分隔。

文件示例:

代码语言:javascript
复制
helloA;lB;lC;lD;lE;lF
A11;bas morning;0;0;5;1.15
B12; Hello WoRlD;-100;11;78;1.33
B11;table;10;0;55;-2.44
C1;OakWood;0;8;17;3.77

任务:计算前两列中不包含字母'B‘或'C’的单词(单词是一个或多个没有‘(空格)的符号)。然后打印那个整数。

我已经完成了大部分任务。我已经从命令行读取了file的名称,读取了该文件,并将整数逐出。但我坚持了一件事。我真的不明白如何逐个检查每一个字。我几乎每次都得到错误的答案。

代码语言:javascript
复制
Input: ( a A a a aba aca;BA A C BA a;1;1;1;1.00) - without brackets.
Output: 6

到目前为止我的代码

代码语言:javascript
复制
org 100h

%include 'yasmmac.inc'

section .text

    startas:
        macPutString 'Write outpu file name', crlf, '$'
        
        ; Reading file from command line
        .commandLine:
            mov bx, 82h
            mov si, 0h
            jmp .checkInputFile

        ; Turns it into ASCIIZ
        .checkInputFile:
            mov cl, [bx+si]
            cmp cl, 20h
            jl .addZero
            inc si
            jmp .checkInputFile
        
        .addZero:
            mov byte [bx+si], 0h
            xor si, si
        
            ; Saving writing file
        mov al, 128         
        mov dx, writingFile
        call procGetStr     
        macNewLine
        
        ; Open reading file
        mov dx, bx
        call procFOpenForReading
        jnc .writingFileIsOpened
        macPutString 'Error while opening reading file', '$'
        exit
        
        ; Atidarome rasymo faila
        .writingFileIsOpened:
            mov [readingDescriptor], bx
            mov dx, writingFile
            call procFCreateOrTruncate
            jnc .openWritingFile
            macPutString 'Error while opening writing file', '$'
            jmp .writingError
        
        ; Save writing descriptor
        .openWritingFile:
            mov [writingDescriptor], bx
            
            
        ; Reads first line
        call procReadLine
    
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

        ; Main loop
        .whileNotEndOfFile:
            xor di, di
            xor si, si
            call procReadLine
            
            ; Check first two columns
            ;mov al, ';'

        mov di, line
        mov al, [di]
        cmp al, ' '
        je .nextWord
        cmp al, ';'
        je .nextWord
            
            ; Checking words
            .checkWord:
                mov al, [di]
                inc di
                
                cmp al, byte 'B'
                je .nextWord
                cmp al, byte 'b'
                je .nextWord
                cmp al, byte 'C'
                je .nextWord
                cmp al, byte 'c'
                je .nextWord
                
                cmp al, byte ' '
                je .addNumber
                cmp al, byte ';'
                je .semicolon
                jmp .checkWord

            .nextWord:
                call procNextWord
                jmp .checkWord

            .semicolon:
                call procAddNumber
                inc si
                cmp si, 0x2
                je .skipLine
                jmp .nextWord

            .addNumber:
                call procAddNumber
                jmp .nextWord
            
            ; If this is not the end of file, repeat loop
            .skipLine:
            cmp [readLastLine], byte 0
            je .whileNotEndOfFile
            
            ; Hexadecimal convertion to decimal
           mov dx, lineCount
           mov ax, [lineCount]
           call procUInt16ToStr
           call procPutStr
           macNewLine
           mov si, dx


           .writingToFile:
           lodsb
           cmp al, 0
           jne .writingToFile
           sub si, dx
           lea cx, [si-1]
           mov bx, [writingDescriptor]
           mov ah, 40h
           int 21h

        
        
        ; Closing Files
        .end:
            mov bx, [writingDescriptor]
            call procFClose
        
        .writingError:
            mov bx, [readingDescriptor]
            call procFClose
        
        macPutString 'Program ends', crlf, '$'

        exit
        
%include 'yasmlib.asm'

; void procReadLine()
; Read line to buffer ‘eilute’
procReadLine:
    push ax
    push bx
    push cx
    push si
    
    mov bx, [readingDescriptor]
    mov si, 0


    .loop:
        call procFGetChar
    
        ; End if the end of file or error
        cmp ax, 0
        je .endOfFile
        jc .endOfFile
        
        ; Putting symbol to buffer
        mov [line+si], cl
        inc si
    
        ; Check if there is \n?
        cmp cl, 0x0A
        je .endOfLine
    
        jmp .loop
        
        
    .endOfFile:
        mov [readLastLine], byte 1
    .endOfLine:
    
    mov [line+si], byte '$'
    mov [lineLenght], si
    
    pop si
    pop cx
    pop bx
    pop ax
    ret

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    
procAddNumber:
    push si
    push ax
    push bx
    push cx
    push dx
    
    ;lineCount++
    mov ax, word [lineCount]
    inc ax
    mov [lineCount], ax
    
    pop dx
    pop cx
    pop bx
    pop ax
    pop si
    ret

procNextWord:

    .loop:
        inc di
        mov al, [di]
        cmp al, byte ' '
        je .loop
        jmp .t

    .t:
        cmp al, byte ';'
        je .t2
        jmp .return

    .t2:
        inc di
        mov al, [di]
        cmp al, byte ' '
        je .t2
        jmp .return

    .return: 
        ret


section .data
        
    readingDescriptor:
        dw 0000
        
    writingFile:
        times 128 db 00
        
    writingDescriptor:
        dw 0000
        
    readLastLine:
        db 00
        
    line:
        db 64
        times 66 db '$'
        
    lineLenght:
        dw 0000
    
    lineCount:
        times 128 db 00

GITHUB: yasmmac.inc/yasmlib.span

任何帮助都会得到认可。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2022-11-17 22:12:11

完全从解决主要任务所需的思维过程开始,我得出如下结论:

  • 在检查单词中的字符之前,我跳过所有前面的空格(如果有的话)
  • 如果前面的空格以分号结尾,则它是当前列中最后一个单词的尾随空格。
  • 一个单词在找到空格或分号时结束。
  • .checkWord不会在查找无效字符{BbCc}时提前退出,但会将标志设置为0。
代码语言:javascript
复制
; Main loop
.whileNotEndOfFile:
  call procReadLine
  mov  si, 2       ; Do 2 columns
  mov  di, line
.skipSpaces:
  mov  al, [di]
  inc  di
  cmp  al, ' '
  je   .skipSpaces
  cmp  al, ';'
  je   .q3         ; It's trailing whitespace
  dec  di
.checkWord:
  mov  bx, 1       ; Assuming it will be a 'good' word
.q1:
  mov  al, [di]
  inc  di
  cmp  al, ' '
  je   .q2
  cmp  al, ';'
  je   .q2
  or   al, 32      ; LCase
  cmp  al, 'b'
  jb   .q1
  cmp  al, 'c'
  ja   .q1
  xor  bx, bx      ; One or more invalid chars in current word
  jmp  .q1
     
.q2:
  add  [lineCount], bx  ; BX=[0,1] Counting the 'good' words
  cmp  al, ';'
  jne  .skipSpaces
.q3:
  dec  si          ; Next column ?
  jnz  .skipSpaces
.skipLine:
  cmp  [readLastLine], byte 0
  je   .whileNotEndOfFile

标签lineCount不再是特别好的计数有效的单词,你不会说?

票数 3
EN

Stack Overflow用户

发布于 2022-11-17 18:15:06

mov al, [di] cmp al, ' ' \* je .nextWord \* cmp al, ';' \* je .nextWord \* .checkWord: mov al, [di] inc di

你正在失去字符串中的字符!

考虑一下。在“鼠标蝙蝠”中,.checkWord将获取空格字符,并将DI指向"b",,但然后procNextWord从增量DI开始,有效地从检查中删除"b“。程序的其余部分只看到"at“,并认为这是一个‘好’字。

代码语言:javascript
复制
procNextWord:
        dec  di         ; Correcting DEC
    .t1:
        inc  di
        mov  al, [di]
        cmp  al, ' '
        je   .t1
        cmp  al, ';'
        jne  .return
    .t2:
        inc  di
        mov  al, [di]
        cmp  al, ' '
        je   .t2
    .return: 
        ret

如果您应用了建议的更正,那么还可以更改我用星号标记的行,然后写上:

代码语言:javascript
复制
    cmp  al, ' '
    je   .nextWordEx
    cmp  al, ';'
    je   .nextWordEx

    ...

.nextWordEx:
    inc  di
.nextWord:
    call procNextWord
    jmp  .checkWord

编辑

当您在一个单词中发现一个不合适的字符时,您需要跳过该单词的其余部分的,这不是procNextWord构建的目的!你需要另一个代码:

代码语言:javascript
复制
  cmp  al, 'B'
  je   .skipRemaining
  cmp  al, 'b'
  je   .skipRemaining
  cmp  al, 'C'
  je   .skipRemaining
  cmp  al, 'c'
  je   .skipRemaining
                
  cmp  al, ' '
  je   .addNumber
  cmp  al, ';'
  je   .semicolon
  jmp  .checkWord

.skipRemaining:
  call procSkipRemaining
  jmp  .checkWord

  ...

procSkipRemaining:
  mov  al, [di]
  cmp  al, " "
  je   .return
  cmp  al, ";"
  je   .return
  inc  di
  jmp  procSkipRemaining
.return:
  ret
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74478881

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档