我在这个问题上发现了很多问题,但是,我无法运行我的代码。我的程序应采用一个十六进制值,检查它是否是有效的十六进制字符,然后将十六进制值显示为十进制值。如果是小写的十六进制字符,则需要将其转换为大写。所有这些都需要循环。
除了将十六进制转换为十进制之外,我已经完成了所有这些操作。我认为程序中的代码应该将其转换,但无法编译。我将在代码下方列出编译器错误。如果注释了convert:标签中的代码(最后一行“ jmp display”除外),则程序将按预期运行,但显然不会以十进制显示该值。
使用nasme进行编译:“ nasm -fbin getChar.asm -o getChar.com -l getChar.lst”
我正在dosbox中运行该程序。
; This program gets a char from user and prints it out as a decimal
org 100h ; program start point
section .data
msgIn: DB 13, 10, "Enter a Hex Digit: $"
msgOut: DB 13, 10, "Decimal Value: $"
msgOpt: DB 13, 10, "Enter another?(y or n): $"
errMsg: DB 13, 10, "Illegal character, Enter 0..9 or A..F: $"
HNUM: DB 19H
NUM: DB 0
D: DB 10h
H: DB 16
CNT: DB 0
section .text
continue: ; start of loop
mov dx, msgIn ; offset address of message to display
mov ah, 9 ; print string function
int 21h
mov ah, 1 ; keyboard input sub-program
int 21h ; read character into al
mov cl, al
legal: ; compare input to see if valid
cmp cl, 48 ; cl < 0
jl end_if ; yes, error msg
cmp cl, 70 ; cl > F
jg check_case ; yes, error msg
jmp prntMsg2 ; print value of input
check_case: ; check case of input
cmp cl, 97 ; cl < a
jl end_if ; yes, error msg
cmp cl, 102 ; cl > f
jg end_if ; yes, error msg
jmp to_upper ; need to send to function to convert to upper case
; then pass to prntMsg2
to_upper:
and al, 223 ; convert to upper case(0DFh)
jmp prntMsg2
end_if: ; error message if invalid input
mov ah, 9
mov dx, errMsg ; print error message
int 21h
jmp continue ; get a new value
prntMsg2: ; print second message*****
mov dx, msgOut ; offset of second message
mov ah, 9 ; print string function
int 21h ; display message
convert:
mov cx, 00
mov dx, 00
L6: mov ax, 00
mov al, [HNUM]
div word [D]
mov [HNUM], al
mov bx, ax
mov cl, 0
mov ax, 1
L5:
cmp cl, 00
je L7
mul word [H]
sub cl, 1
jmp L5
L7:
mul bh
add dx, ax
add word [CNT], 1
cmp word [HNUM], 0
jg L6
mov [NUM], dl
jmp display
display: ; display character
mov dl, al
mov ah, 2 ; print char function
int 21h
mov ah, 9 ; see if user wants to do it again
mov dx, msgOpt
int 21h
mov ah, 1
int 21h
mov bl, al
cmp bl, 'y' ; bl = y
jne exitPrg ; no, end
jmp continue ; get a new value
exitPrg: ; exit program
mov ah, 4ch ; exit to DOS function
int 21h ; see you later!
上面的代码已被编辑,现在可以编译和运行。但是,它仍然没有正确执行从十六进制到十进制的转换。它只是不显示值,而只是空白。如果输入了字母,甚至是字母af,它也会挂断。数字不会挂断电话,但仍然不会显示值。
现在,我至少可以运行它,但可以修复它,但是,任何指导都值得赞赏。感谢吉恩(Gene)让我起跑。
NASM内存操作数使用方括号表示取消引用。因此,例如,您将需要:
mov al, [HNUM]
div byte [D]
mov [HNUM], al
在NASM手册说明这一点。RTFM!
如果没有括号,则将标签视为等于存储位置地址的立即操作数。第一行没有语法错误,但是会导致al
加载地址的低字节HNUM
。不是您想要的。这div
是一个错误,因为8086没有指令除以立即数。而且这mov
是胡说八道,因为您无法写入立即数。
因此,错误消息告诉您出了什么问题。在所引用的行中,操作数与它们的指令不符。
添加
我继续安装了dosbox和NASM。确实,NASM在推断操作数类型方面不如MASM聪明。因此,对于div
说明,您需要byte
,而不是word
上面所示的。我无法理解您的算法。它比必要的更为复杂。这是我的版本:
; This program gets a hex digit from user and prints it out as a decimal
org 100h ; program start point
section .data
msgIn: DB 13, 10, "Enter a hex digit or q to quit: $"
msgErr: DB " isn't hex. Must be 0-9, A-F, or a-f.$"
msgOut: DB " has decimal value $"
buffer: DB "xxxxx"
endBuf: DB ".$"
ten: DB 10
section .text
continue: ; start user interaction
mov dx, msgIn ; offset address of message to display
mov ah, 9 ; print string function
int 21h
get_hex_digit:
mov ah, 1
int 21h ; read character into al
check_for_quit:
cmp al, 'q' ; handle quit character
je exit
cmp al, 'Q'
je exit
check_for_digit:
cmp al, '0' ; handle 0-9
jl check_for_upper
cmp al, '9'
jg check_for_upper
sub al, '0' ; convert to numeric value
jmp print_decimal
check_for_upper:
cmp al, 'A' ; handle A-F
jl check_for_lower
cmp al, 'F'
jg check_for_lower
sub al, 'A'-10 ; convert to numeric value
jmp print_decimal
check_for_lower:
cmp al, 'a' ; handle a-f
jl handle_digit_error
cmp al, 'f'
jg handle_digit_error
sub al, 'a'-10 ; convert to numeric value
print_decimal: ; print al contents as decimal 0-255
mov di, endBuf ; set buffer pointer to char after digits
next_digit:
dec di ; advance buffer pointer to next char
xor ah, ah ; clear high byte of ax for division
div byte [ten] ; ah = ax % 10, al = ax / 10
add ah, '0' ; convert ah to ascii
mov [di], ah ; copy to buffer
or al, al ; set condition codes with al
jnz next_digit ; jump if more digits to print
print_digits:
mov dx, msgOut ; offset address of message preamble
mov ah, 9 ; print string function
int 21h
mov dx, di ; offset address of converted digits
mov ah, 9 ; print string function
int 21h
jmp continue ; otherwise, get next input
handle_digit_error:
mov dx, msgErr ; offset address of message to display
mov ah, 9 ; print string function
int 21h
jmp continue
exit: ; exit program
mov ah, 4ch ; exit to DOS function
int 21h ; see you later!
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句