大会:如何转换输入十六进制到十进制? [英] Assembly: How to convert hex input to decimal?
问题描述
我发现有很多问题,但是,我一直没能得到我的code运行。我的程序应该采取一个十六进制值,检查,看它是否是一个有效的十六进制字符,然后显示十六进制值作为一个十进制值。如果它是一个小写十六进制字符,则需要被转换为大写。所有这需要在一个循环
I have found many questions on this issue, however, I have not been able to get my code to run. My program should take a hex value, check to see if it is a valid hex character, then display the hex value as a decimal value. If it is a lower case hex character then it needs to be converted to upper case. All this needs to be in a loop.
我有这一切,除了转换十六进制到十进制完成。我在节目中,我认为应该把它转换了code,但它不会编译。我将列出以下code编译器错误。如果在标签转换code:被注释掉了(除了最后一行,JMP显示),则程序会运行,因为它应该,但显然不会显示该值作为一个十进制
I have all of this done except for converting the hex to decimal. I have the code in the program I think should convert it, but it will not compile. I will list the compiler errors below the code. If the code in the label convert: is commented out(except for the last line, "jmp display") then the program will run as it should, but obviously will not show the value as a decimal.
与nasme编译:NASM -fbin getchar.asm中-o getChar.com -l getChar.lst
Compiling with nasme: "nasm -fbin getChar.asm -o getChar.com -l getChar.lst"
我运行在DOSBox中的程序。
I am running the program in 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!
在code以上已被编辑,现在编译和运行。然而,它仍然不能从十六进制执行转换到正确十进制。它根本不显示数值,只是空白。它也将挂断如果输入一个字母,甚至一个字母A-F。许多不挂起来,但仍然没有显示的值。
The code above has been edited and now compiles and runs. However, it is still not doing the conversion from hex to decimal correctly. It simply doesn't display a value, just blank. It will also hang up if a letter is entered, even a letter a-f. A number does not hang it up, but still a value is not displayed.
现在我有它运行至少我可以修复它工作,但是,任何指导AP preciated。由于基因的让我启动和运行。
Now that I have it running at least I can work on fixing it, however, any guidance is appreciated. Thanks Gene for getting me up and running.
推荐答案
NASM内存操作数使用方括号来表示提领。因此,例如,你会想:
NASM memory operands use square brackets to denote dereferencing. So for example you will want:
mov al, [HNUM]
div byte [D]
mov [HNUM], al
借助 NASM手册解释这一点。 RTFM!
The NASM Manual explains this. RTFM!
没有括号,标签是作为立即操作数等于存储器单元的地址进行处理。第一行是没有语法错误,但导致人
加载与 HNUM
地址的低字节。不是你想要的。在 DIV
是一个错误,因为8086没有指令通过即时数量来划分。和 MOV
是无稽之谈,因为你不能写一个直接的价值。
Without the brackets, the labels are treated as immediate operands equal to the address of the memory location. The first line is no syntax error, but causes al
to be loaded with the low byte of the address of HNUM
. Not what you wanted. The div
is an error because 8086 has no instruction to divide by an immediate quantity. And the mov
is nonsense because you can't write to an immediate value.
因此,错误信息,告诉你什么是错的。在引用的线条,操作数不与他们的指导相称。
So the error messages are telling you what's wrong. In the lines referenced, the operands do not comport with their instructions.
加入
我继续安装DOSBox中和NASM。事实上NASM是不是很MASM智能推断左右操作数类型。所以对于 DIV
指令需要字节
,(未字
)像现在上面反映。我不能神交你的算法。它比必要更复杂。这里是我的版本:
I went ahead and installed dosbox and NASM. Indeed NASM is not quite as smart as MASM about inferring operand types. So for the div
instruction you need byte
, (not word
) as now reflected above. I could not grok your algorithm. It's more complicated than necessary. Here is my version:
; 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!
这篇关于大会:如何转换输入十六进制到十进制?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!