【问题标题】:How can I get user's hex input to print as decimal in x86 assembly (16-bit DOS)?如何在 x86 程序集(16 位 DOS)中将用户的十六进制输入打印为十进制?
【发布时间】:2016-01-11 22:02:40
【问题描述】:

我向我的教授寻求帮助。他的任期很深,并不在乎,所以他只是给了我一个模糊的解决方案。基本任务是获取用户输入(十六进制值),将值转换为十进制,然后将其打印出来。这是我的代码:

; 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”。我到底做错了什么?

【问题讨论】:

    标签: assembly x86 hex nasm


    【解决方案1】:

    显然,您不知道pop 做了什么。请参阅指令集参考。

    提示:你想要push ax,你有pop bx,你想要pop dx,你有mov dl,bl

    你的sub al,65 也是错误的,因为它转换为0..5 而不是'0'..'5'(即你想要sub al, 17

    【讨论】:

    • 成功了。谢谢!不,我想我对推送和流行的动态并不完全清楚。我们在课堂上几乎没有触及它,这并不重要。就像我说的那样,我的教授对他的任期如此深入,他不想解释它。如果你不介意,你能解释一下你的解决方案吗?我想了解它是如何工作的。
    • push 只是将其操作数保存在堆栈中,pop 检索它。因为我们需要dl 中的东西,所以我弹出了dx,你不需要使用相同的寄存器。我相信你对最后一段没有问题。
    • 我确实将其更改为 sub al, 17,这在我查看了 ASCII 表之后才有意义。我将它设置为 65,因为这实际上是我的教授告诉我的。他几乎没有注意,实际上解释到一半就走了。任期。无论如何,在阅读了有关堆栈的更多信息之后,我想我已经确定了我的困惑来源。也许我还有点不清楚,但我猜我认为我在推送之前通过弹出来做的是从调用堆栈中获取一些东西,据我所知,这是一个处理局部变量的隐式堆栈。
    猜你喜欢
    • 2013-09-23
    • 1970-01-01
    • 2015-02-14
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    • 2020-05-14
    • 2016-08-21
    • 2022-11-29
    相关资源
    最近更新 更多