我在这个问题上找到了很多问题,但是,我无法运行我的代码。我的程序应采用十六进制值,检查它是否是有效的十六进制字符,然后将十六进制值显示为十进制值。如果它是小写十六进制字符,则需要将其转换为大写。所有这些都需要循环。
除了将十六进制转换为十进制之外,我完成了所有这些操作。我有程序中的代码,我认为应该转换它,但它不会编译。我将列出代码下面的编译器错误。如果标签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!
上面的代码已经过编辑,现在可以编译和运行。但是,它仍然没有正确地从十六进制转换为十进制。它根本不显示值,只是空白。如果输入一封信,即使是字母a-f,它也会挂断。数字不会挂起,但仍然不会显示值。
现在我已经运行了至少我可以修复它,但是,任何指导都表示赞赏。感谢Gene让我开始运行。
答案 0 :(得分:0)
NASM内存操作数使用方括号表示解除引用。例如,您需要:
mov al, [HNUM]
div byte [D]
mov [HNUM], al
NASM Manual解释了这一点。 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!
答案 1 :(得分:0)
check_for_upper:
cmp al, 'A' ; handle A-F
jl check_for_lower
这应该是:
jl handle_digit_error
因为Ucase“A”是41h,Lcase“a”是61h