【问题标题】:How to enter an 32 bit number in assembly?如何在汇编中输入 32 位数字?
【发布时间】:2012-08-24 05:05:53
【问题描述】:

我在 Tasm 中编程,想输入一个 32 位数字。

我知道我必须逐位输入(我希望没有一个号码输入的呼叫功能)

这是我的代码

    .        .486
    .model small
    .code
    start:

    mov ebx, 0

    ; enter again and again untill enter is hit
    again:
    mov ah,01h
    int 21h
    cmp al, 13
    jz next
    mov dl, al
    mov eax, ebx
    mov ebx, 10
    mul ebx
    mov ebx, eax
    mov eax, 0
    mov al, dl
    add ebx, eax
    jmp again

    ; now find the digits back

    next:
    ; just testing to see if i got number
    mov edx, 13
    mov ah, 02h
    int 21h

    mov edx, 10
    mov ah,02h
    int 21h

    mov edx, ebx
    mov ah, 02h
    int 21h

    mov eax, ebx

    mov ebx, eax

    xor edx, edx
    xor cl, cl

    ; find digits and push into stack from last to first so when i pop i get digits back
    finddigit:
    xor edx,edx
    mov ch , 10
    div ch
    push dx ;taking risk dx dl
    inc cl
    cmp eax, 0
    jz print
    jmp finddigit


    ; stored into cl the number of digits

    print:
    cmp cl,0
    jz exit
    dec cl
    pop dx
    mov ah,02h
    int 21h
    jmp print


    exit:
    end start

我正在停止输入。

我收到错误 NTVDM 遇到一个硬错误。

谢谢

这是我修改后的新代码。它适用于 2 和 123 等数字 但 333、4444、555 失败; (我希望 push 和 poping 不会修改指定以外的任何寄存器):

.486
.model small
.code
start:

mov ebx, 0

; enter again and again untill enter is hit
again:
mov ah,01h
int 21h
cmp al, 13
jz next
mov cl, al
sub cl, 30h
mov eax, ebx
mov ebx, 10
mul ebx
mov ebx, eax
mov eax, 0
mov al, cl
add ebx, eax
jmp again

; now find the digits back

next:
; just testing to see if i got number
mov edx, 13
mov ah, 02h
int 21h

mov edx, 10
mov ah,02h
int 21h


mov eax, ebx

mov ebx, eax

xor ecx, ecx

mov ebx, ebp
; find digits and push into stack from last to first so when i pop i get digits back
finddigit:
xor edx,edx
mov ebp , 10
div ebp
push edx
inc cl
cmp eax, 0
jz print
jmp finddigit

; stored into cl the number of digits

print:
cmp cl,0
jz exit
dec cl
xor edx,edx
pop edx
add dl,30h
mov ah,02h
int 21h
jmp print


exit:
mov ah,4ch
int 21h               
end start

我在运行这个是MS-DOS CMD.exe窗口弹出错误来:

【问题讨论】:

    标签: assembly input x86 dos digit


    【解决方案1】:

    假设这是针对 DOS 环境(由于int 21h):

    您的代码中有一些错误。

    1.读取字符函数在al中返回它的输出,没关系。但是随后您立即使用以下顺序销毁读取字符的值:

        mov dl, al    ; the character read now in dl
        mov eax, ebx  ; eax is now 0 in the first loop
        mov ebx, 10   ; ebx is now 10
        mul ebx       ; the result of mul ebx is now in edx:eax,
                      ; the character read (in dl) is lost.
    

    因此,如果要执行mul ebx,则不能将字符存储在dl 中,因为mul reg32 会在edx:eax 中输出结果。你可以存储它,例如。改为clch

    2. 我注意到的其他错误是您试图将 ASCII 值乘以 10(在前面的代码中)。在乘法之前,您应该首先减去每个读取字符的“0”值,即sub al, 30hsub al, '0'

    3. 第三个 bug 顺序如下:

       xor edx,edx
       mov ch , 10
       div ch
       push dx ;taking risk dx dl
       inc cl
       cmp eax, 0
       jz print
       jmp finddigit
    

    编辑:在这里,您将ax 除以ch,这显然不适用于32 位除法。似乎您希望在eax 中获得红利,用xor edx, edx 清除edx(就像你一样),然后用32 位寄存器除edx:eax,例如。 ebpesiedi(到目前为止,您的代码中似乎没有使用这些),您将获得 eax 中的商和 edx 中的余数。

    【讨论】:

    • 在你的“exit:”标签上还需要一个“exit”(mov ah, 4Ch/int 21h)。这可能就是 NTDVM 所抱怨的。
    • @nrz 我已经更新了这个问题。粘贴了新代码。它对某些输入工作正常,但对其他输入则失败。
    • 作为一般的“经验法则”,当出现设计错误时,不要费心修复实现错误。要修复设计错误(例如,当用户按下“退格”或“home 然后删除”时会发生什么?)你应该从用户那里得到一个字符串;然后稍后将字符串转换为整数(带有错误检查,包括无效字符和溢出/范围)。
    • @Brendan 我们一步步朝着目标前进;我想先完成基本输入,然后专注于其他重要细节。我正在学习汇编; :)
    • @ASHISHNEGI 最初的问题是关于DOS环境的32位汇编代码中的错误,在我看来,原始代码中的错误已经解决了。与在 Windows NT 中的 NTVDM 虚拟 DOS 机中运行 32 位 DOS 代码相关的问题超出了原始问题的范围,因此您应该发布一个关于它的新问题,也许有人可以在这方面为您提供帮助。您还可以在 386+ 计算机中尝试 DOS 中的代码,这样可以确认代码在 DOS 中运行没有问题。您也可以尝试使用 DOSBOX 或其他一些 DOS 模拟器来代替 NTVDM。
    猜你喜欢
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 2014-01-09
    • 2021-03-17
    • 1970-01-01
    • 2013-12-20
    • 1970-01-01
    相关资源
    最近更新 更多