我正在编写一个程序,将数字转换为单词,并将所有其他字符不变地写入输出文件。但由于某种原因,输出缓冲区会相互覆盖字符。前任。输入文件如下所示:0a;输出文件应如下所示:nulisa.相反,它看起来像这样:aulis。这是我到目前为止所拥有的:
.model small
.stack 100h
.data
msgHelp DB "Usage: program.exe <input_file> <output_file>$"
msgFileError DB "Error: File not found or cannot be opened.$"
input db 200 dup (0)
output db 200 dup (0)
skBuf db 20 dup (?)
raBuf db 200 dup (?)
words db "nulis", 0, "vienas", 0, "du", 0, "trys", 0, "keturi", 0, "penki", 0, "sesi", 0, "septyni", 0, "astuoni", 0, "devyni", 0
wordOffsets dw 0, 6, 13, 16, 21, 28, 34, 39, 47, 55
dFail dw ?
rFail dw ?
raBufPos dw 0
.code
start:
MOV ax, @data
MOV ds, ax
MOV di, offset raBuf
MOV bx, 82h
MOV si, offset input
cmp byte ptr es:[80h], 0
je help
cmp es:[82h], '?/'
jne check_param
cmp byte ptr es:[84h], 13
je help
jmp check_param
help:
mov ah, 9
mov dx, offset msgHelp
int 21h
jmp programEnd
check_param:
cmp byte ptr es:[bx], 13
je next_filename
cmp byte ptr es:[bx], 32
je next_filename
mov dl, byte ptr es:[bx]
mov [si], dl
inc bx
inc si
jmp check_param
next_filename:
inc bx
mov si, offset output
output_filename_loop:
cmp byte ptr es:[bx], 13
je found
mov dl, byte ptr es:[bx]
mov [si], dl
inc bx
inc si
jmp output_filename_loop
found:
MOV ah, 3Dh
MOV al, 00
MOV dx, offset input
INT 21h
JC file_error
MOV dFail, ax
MOV ah, 3Ch
MOV cx, 0
MOV dx, offset output
INT 21h
JC file_error
MOV rFail, ax
read:
MOV bx, dFail
CALL ReadBuf
CMP ax, 0
JE closeInput
MOV cx, ax
MOV si, offset skBuf
processLoop:
MOV dl, [si]
CMP dl, '0'
JB notDigit
CMP dl, '9'
JA notDigit
PUSH cx
PUSH si
PUSH di
CALL ConvertDigitToWord
POP di
POP si
POP cx
JMP skip
notDigit:
MOV [di], dl
INC di
INC raBufPos
skip:
INC si
DEC cx
JNZ processLoop
writeOutput:
MOV cx, raBufPos
MOV bx, rFail
MOV dx, offset raBuf
CALL WriteBuf
MOV di, offset raBuf
MOV raBufPos, 0
JMP read
file_error:
MOV ah, 09h
MOV dx, offset msgFileError
INT 21h
jmp programEnd
closeOutput:
MOV ah, 3Eh
MOV bx, rFail
INT 21h
JC file_error
closeInput:
MOV ah, 3Eh
MOV bx, dFail
INT 21h
programEnd:
MOV ah, 4Ch
MOV al, 0
INT 21h
ConvertDigitToWord PROC
SUB dl, '0'
MOV cl, dl
MOV si, offset wordOffsets
MOV bx, cx
SHL bx, 1
ADD si, bx
MOV ax, [si]
ADD ax, offset words
MOV si, ax
copyWord:
MOV al, [si]
CMP al, 0
JE doneCopy
MOV [di], al
INC di
INC si
INC raBufPos
JMP copyWord
doneCopy:
RET
ConvertDigitToWord ENDP
ReadBuf PROC
MOV ah, 3Fh
MOV bx, dFail
MOV cx, 20
MOV dx, offset skBuf
INT 21h
RET
ReadBuf ENDP
WriteBuf PROC
MOV ah, 40h
MOV bx, rFail
MOV cx, raBufPos
MOV dx, offset raBuf
INT 21h
RET
WriteBuf ENDP
END start
PUSH cx PUSH si PUSH di CALL ConvertDigitToWord POP di POP si POP cx
DI 寄存器目前仅是ConvertDigitToWord 程序的输入。但对于您的程序来说,它也应该是此过程的“输出”。通过删除 PUSH di
和
POP di
指令快速解决该问题。想要更好吗?然后避免冗余。
都起着类似的作用。您不需要那个 raBufPos 变量。
只需像您在 mov di, offset raBuf
中所做的那样设置 DI,并且在需要输出长度的地方可以将
MOV cx, raBufPos
替换为 lea cx, [di - raBuf]
。如果您的汇编器不接受这一点,则将其写为 mov cx, di
sub cx, offset raBuf
。ps。请编辑您的帖子并将整个程序放在三个反引号字符之间。