如何让用户的十六进制输入在 x86 程序集(16 位 DOS)中打印为十进制?
How can I get user's hex input to print as decimal in x86 assembly (16-bit DOS)?
我向我的教授寻求帮助。他的任期很深,并不在乎,所以他只是给了我一个模糊的问题解决方案。基本任务是获取用户输入(十六进制值),将值转换为十进制,然后按原样打印出来。这是我的代码:
; SECOND ASSIGNMENT
org 100h
;equates
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
section .data
prompt0: db 0dh, 0ah, "My name is Brandon Copeland. Prepare to enter data! $"
prompt1: db 0dh, 0ah, "Enter a hex digit: $"
prompt2: db 0dh, 0ah, "In decimal it is: $"
prompt3: db 0dh, 0ah, "Do you want to do it again? Press 'y' or 'Y' to continue $"
prompt4: db "Illegal entry: must be 0 - 9 or A - F $"
section .text
start:
mov ah,9 ;Display string
mov dx,prompt0 ;Greeting
int 21h ;System call
mov ah,9 ;Display string
mov dx,prompt1 ;Prompt for first number
int 21h ;System call
mov bx,0 ;bx holds input value
mov ah,1 ;Reads keyboard character
int 21h ;System call
cmp al, '9' ;compares input to '9'
je print ;if 9, jump to print
jl print ;if less than 9, jump to print
ja decConvert ;if greater than 9, convert A - F to 10 - 15
decConvert:
and al,11011111b ; force uppercase
sub al,65 ; convert 'A'-'F' to 10-15
pop bx
mov ah,9
mov dx,prompt2
int 21h
mov ah,2 ;print char
mov dl,'1' ;print '1'
int 21h
mov ah,2
mov dl,bl
int 21h
jmp repeat
print:
mov ah,9
mov dx, prompt2
int 21h
mov ah,2
mov dl,al
int 21h
repeat:
mov ah,9
mov dx, prompt3 ;asks user if wants to do again
int 21h
mov bx,0 ;gets user answer
mov ah,1
int 21h
cmp al,'y' ;if y, restart
je start
cmp al,'Y' ;if Y, restart
je start
jmp exit ;otherwise, terminate program ;
exit:
mov ah,04ch ;DOS function: exit
mov al,0 ;exit code
int 21h ;call DOS, exit
在走开之前,我的教授提到由于所有十六进制值 A - F 都以“1”开头,我可以只打印一次“1”,然后打印下一个数字,我会将 al 的内容弹出到另一个寄存器中。如果您查看标签 "decConvert,",我将 al 弹出到 bx,然后尝试打印 bl。
数字 0 - 9 的输出没问题。但是,每当我尝试输入 A - F 时,每次输出都只是“1”。我到底做错了什么?
你显然不知道 pop
是做什么的。查阅指令集参考。
提示:你想要 push ax
的地方有 pop bx
,你想要 pop dx
的地方有 mov dl,bl
。
你的 sub al,65
也是错误的,因为它转换为 0..5
而不是 '0'..'5'
(即你想要 sub al, 17
)
我向我的教授寻求帮助。他的任期很深,并不在乎,所以他只是给了我一个模糊的问题解决方案。基本任务是获取用户输入(十六进制值),将值转换为十进制,然后按原样打印出来。这是我的代码:
; SECOND ASSIGNMENT
org 100h
;equates
cr equ 0dh ;carriage return
lf equ 0ah ;line feed
section .data
prompt0: db 0dh, 0ah, "My name is Brandon Copeland. Prepare to enter data! $"
prompt1: db 0dh, 0ah, "Enter a hex digit: $"
prompt2: db 0dh, 0ah, "In decimal it is: $"
prompt3: db 0dh, 0ah, "Do you want to do it again? Press 'y' or 'Y' to continue $"
prompt4: db "Illegal entry: must be 0 - 9 or A - F $"
section .text
start:
mov ah,9 ;Display string
mov dx,prompt0 ;Greeting
int 21h ;System call
mov ah,9 ;Display string
mov dx,prompt1 ;Prompt for first number
int 21h ;System call
mov bx,0 ;bx holds input value
mov ah,1 ;Reads keyboard character
int 21h ;System call
cmp al, '9' ;compares input to '9'
je print ;if 9, jump to print
jl print ;if less than 9, jump to print
ja decConvert ;if greater than 9, convert A - F to 10 - 15
decConvert:
and al,11011111b ; force uppercase
sub al,65 ; convert 'A'-'F' to 10-15
pop bx
mov ah,9
mov dx,prompt2
int 21h
mov ah,2 ;print char
mov dl,'1' ;print '1'
int 21h
mov ah,2
mov dl,bl
int 21h
jmp repeat
print:
mov ah,9
mov dx, prompt2
int 21h
mov ah,2
mov dl,al
int 21h
repeat:
mov ah,9
mov dx, prompt3 ;asks user if wants to do again
int 21h
mov bx,0 ;gets user answer
mov ah,1
int 21h
cmp al,'y' ;if y, restart
je start
cmp al,'Y' ;if Y, restart
je start
jmp exit ;otherwise, terminate program ;
exit:
mov ah,04ch ;DOS function: exit
mov al,0 ;exit code
int 21h ;call DOS, exit
在走开之前,我的教授提到由于所有十六进制值 A - F 都以“1”开头,我可以只打印一次“1”,然后打印下一个数字,我会将 al 的内容弹出到另一个寄存器中。如果您查看标签 "decConvert,",我将 al 弹出到 bx,然后尝试打印 bl。
数字 0 - 9 的输出没问题。但是,每当我尝试输入 A - F 时,每次输出都只是“1”。我到底做错了什么?
你显然不知道 pop
是做什么的。查阅指令集参考。
提示:你想要 push ax
的地方有 pop bx
,你想要 pop dx
的地方有 mov dl,bl
。
你的 sub al,65
也是错误的,因为它转换为 0..5
而不是 '0'..'5'
(即你想要 sub al, 17
)