我的程序中的问题是当我尝试从包含字符串的缓冲区中取一个字符时,将一个字符分配给AL
寄存器并调用一个过程,该过程转换{{1}中的字符对HEX,我得到一个无限循环。这是我的代码:
AL
我的意见是获得这样的输出:
.model small
.stack 100H
.data
about db 'example.exe [/?] [sourceFile2]]',13,10,13,10,9,'/? - help',13,10,'$'
err_s db 'Unable to open source file',13,10,'$'
str_term db '$'
sourceF db 12 dup (0)
sourceFHandle dw ?
buffer db 500 dup (?)
.code
START:
mov ax, @data
mov es, ax ; es so we can use stosb function: Store AL at address ES:(E)DI
mov si, 81h
call skip_spaces
mov al, byte ptr ds:[si] ; read first symbol of program parameter
cmp al, 13 ; if there's no parameters
jne _1
jmp help ; then jump to help
_1:
;; do we need to print out help
mov ax, word ptr ds:[si]
cmp ax, 3F2Fh ; if input is "/?" - 3F = '?'; 2F = '/'
jne _2
jmp help ; if "/?" is found, print out help
_2:
;; source file name
lea di, sourceF
call read_filename ; move from parameter to line
push ds
push si
mov ax, @data
mov ds, ax
jmp startConverting
readSourceFile:
pop si
pop ds
;; source file name
lea di, sourceF
call read_filename ; move from parameter to line
push ds
push si
mov ax, @data
mov ds, ax
cmp byte ptr ds:[sourceF], '$' ; if there was nothing to read
jne startConverting
jmp closeF
startConverting:
;; open
cmp byte ptr ds:[sourceF], '$' ; if there was nothing to read
jne source_from_file
mov sourceFHandle, 0
jmp read
source_from_file:
mov dx, offset sourceF ; file name
mov ah, 3dh ; open file command
mov al, 0 ; 0 - reading, 1-writing
int 21h ; INT 21h / AH= 3Dh - open existing file
jc err_source ; CF set on error AX = error code.
mov sourceFHandle, ax ; save filehandle
read:
mov bx, sourceFHandle
mov dx, offset buffer ; address of buffer in dx
mov cx, 500 ; how many bytes to read
mov ah, 3fh ; function 3Fh - read from file
int 21h
mov cx, ax ; bytes actually read
cmp ax, 0 ; if there was nothing to read
jne _6 ; not the end of file
mov bx, sourceFHandle ; end of the file being read
mov ah, 3eh ; close the file
int 21h
jmp readSourceFile ; open another file to read if it was specified in the parameters
_6:
mov si, offset buffer ; read from buffer
cmp sourceFHandle, 0
jne _7
cmp byte ptr ds:[si], 13
je closeF
_7:
push cx ; save big loop CX
sort_out:
lodsb ; Load byte at address DS:(E)SI into AL
push cx ; place cx
mov ah, 40h ; INT 21h / AH= 40h - write to file
int 21h
pop cx
loop sort_out
pop cx
loop read
help:
mov ax, @data
mov ds, ax
mov dx, offset about
mov ah, 09h
int 21h
jmp _end
closeF:
;; close the destination file
mov ah, 3eh ; close
int 21h
result:
MOV si, offset buffer ; source index = buffer coordinates
INC si ; add 1 to si
MOV bh, [si] ; let bh know how many symbols in total
INC si ; go to the symbol itself
mov bl, 0 ; initialize bl counter to 0
jmp char
; print out the text in buffer
mov dx, offset buffer
mov ah, 09h
int 21h
_end:
; add a string terminator to avoid static output
db '$'
mov ax, @data
mov ax, 4c00h
int 21h
char:
LODSB ; take a character from es:si and add it to al
; increment bl
INC bl
MOV dl, al ; add a symbol from al to dl
mov ah,2
int 21h
; try to convert the current symbol in al to HEX and print it out
; =======INFINITE LOOP PROBLEM HERE========
call char_to_hex
DEC bh ; subtract 1 from total amount of symbols
JZ _end ; if bh = 0, end program
JMP char ; if not, jump to other symbol
err_source:
mov ax, @data
mov ds, ax
mov dx, offset err_s
mov ah, 09h
int 21h
mov dx, offset sourceF
int 21h
mov ax, 4c01h
int 21h
;; procedures
skip_spaces PROC near
skip_spaces_loop:
cmp byte ptr ds:[si], ' '
jne skip_spaces_end
inc si
jmp skip_spaces_loop
skip_spaces_end:
ret
skip_spaces ENDP
read_filename PROC near
push ax
call skip_spaces
read_filename_start:
cmp byte ptr ds:[si], 13 ; if there is no parameters
je read_filename_end ; if yes, its the end of the filename
cmp byte ptr ds:[si], ' ' ; if space
jne read_filename_next ; then skip it and jump to the next parameter
read_filename_end:
mov al, '$' ; add '$' to the end
stosb ; Store AL at address ES:(E)DI, di = di + 1
pop ax
ret
read_filename_next:
lodsb ; loads other symbol
stosb ; Store AL at address ES:(E)DI, di = di + 1
jmp read_filename_start
read_filename ENDP
; Char to Hex converting
char_to_hex PROC ; Accept a character, print it's ascii value in hex.
MOV DX, OFFSET AskChar ; Display prompt
MOV AH, 09H
INT 21H
MOV AH, 07H ; Get keyboard input w/ no echo (AL)
INT 21H
MOV CL, AL ; Copy user input (AL) to CL
MOV AX, 0 ; Clear AX (get rid of HO bits)
MOV AL, CL ; Copy user input back into AL
MOV BX, 16 ; Set up the divisor (base 16)
MOV CX, 0 ; Initialize the counter
MOV DX, 0 ; Clear DX
Div2:
; Dividend (what's being divided) in DX/AX pair, Quotient in AX, Remainder in DX.
DIV BX ; Divide (will be word sized).
PUSH DX ; Save DX (the remainder) to stack.
ADD CX, 1 ; Add one to counter
MOV DX, 0 ; Clear Remainder (DX)
CMP AX, 0 ; Compare Quotient (AX) to zero
JNE Div2 ; If AX not 0, go to "Div2:"
getHex2:
MOV DX, 0 ; Clear DX.
POP DX ; Put top of stack into DX.
ADD DL, 30h ; Conv to character.
CMP DL, 39h
JG MoreHex2
HexRet2:
MOV AH, 02h ; 02h to display AH (DL)
INT 21H ; Send to DOS
LOOP getHex2 ; If more to do, getHex2 again
; LOOP subtracts 1 from CX. If non-zero, loop.
JMP Skip2
MoreHex2:
ADD DL, 7h
JMP HexRet2 ; Return to where it left off before adding 7h.
Skip2:
RET
char_to_hex ENDP
end START
即使我的程序需要更多的工作来获得这样的结果,我至少也希望将转换字符转换为十六进制部分。
答案 0 :(得分:0)
您是否从另一项练习中取出char_to_hex
并将其粘贴到此计划中?这可以解释这一部分:
; Char to Hex converting
char_to_hex PROC ; Accept a character, print it's ascii value in hex.
MOV DX, OFFSET AskChar ; Display prompt
MOV AH, 09H
INT 21H
MOV AH, 07H ; Get keyboard input w/ no echo (AL)
INT 21H
我无法在任何地方找到AskChar
符号,所以谁知道正在打印什么 - 但是最后两行在键盘上等待(耐心地)给它一个角色。这可能是“无限循环”吗?
答案 1 :(得分:0)
char_to_hex
clobbers bx
,您在使用bh
作为循环计数器的循环中调用它。
如果您在调试器中运行代码,那么您可以自己找到这个,这样您就可以在运行时查看寄存器值。