我一直在做這個專案。主要目標是計算有多少單詞不包含字母“B”或“C”。給定檔案有 [0;1000] 行。每行包含 6 列。
前兩列包含帶 [1; 20] 個字符。字符可以是字母、數字和空格。
3-5 列包含 [-100 范圍內的整數;100]。第 6 列包含 [-9.99 范圍內的實數;9.99] 小數點后只有兩位數。
我用分號“;”分隔每個部分。
檔案示例:
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'。并列印那個整數。
我已經處理了大部分任務。我已經從命令列讀取檔案名,讀取檔案,輸出整數。但我一直堅持一件事。我真的不明白如何一個一個地檢查每個單詞。我幾乎每次都得到錯誤的答案。
Input: ( a A a a aba aca;BA A C BA a;1;1;1;1.00) - without brackets.
Output: 6
到目前為止我的代碼
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.asm
任何幫助將不勝感激。
uj5u.com熱心網友回復:
完全重新開始解決主要任務所需的思考程序,我得出以下結論:
- 在檢查單詞中的字符之前,我跳過所有前導空格(如果有的話)
- 如果前導空格以分號結尾,則它是當前列中最后一個單詞的尾隨空格
- 找到空格或分號時單詞結束
- .checkWord不會提前發現無效字符 {BbCc},而是將標志設定為 0
; 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不再特別適合計算有效單詞,你說呢?
uj5u.com熱心網友回復:
mov al, [di] cmp al, ' ' * je .nextWord * cmp al, ';' * je .nextWord * .checkWord: mov al, [di] inc di
您正在丟失字串中的字符!
考慮例如。“mouse bat”,其中.checkWord將獲取空格字符并使 DI 指向“b”,但隨后procNextWord通過遞增 DI 開始,有效地從檢查中洗掉“b”。程式的其余部分只看到“at”并認為這是一個“好”字。
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
如果您應用建議的更正,那么還要更改我用星號標記的行并寫下:
cmp al, ' '
je .nextWordEx
cmp al, ';'
je .nextWordEx
...
.nextWordEx:
inc di
.nextWord:
call procNextWord
jmp .checkWord
[編輯]
當您在一個單詞中發現一個不合適的字符時,您需要跳過該單詞的其余部分,而procNextWord并不是為此而構建的!你需要另一個代碼:
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
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/537479.html
標籤:部件x86亚斯姆
