【问题标题】:Infinite loop after dividing in assembly NASM在汇编 NASM 中划分后的无限循环
【发布时间】:2014-10-19 09:19:15
【问题描述】:

我正在尝试在 NASM 程序集中编写一个将十进制数转换为二进制数的程序。 到目前为止,我编写了一些代码,将输入数字除以 2 并显示余数。但是我有一个问题,除法后我得到一个无限循环,实际上我在eax中总是有一个大于0的数字。

; ----------------------------------------------------------------------------------------
; nasm -felf decbin.asm && gcc decbin.o -o decbin
; ----------------------------------------------------------------------------------------
section .data
    in_message  db  "Enter a number in decimal:",0 ;input message
    out_message db  "The binary number is:%d",10,0 ;output message
    integer times 4 db  0                  ;32bits integer
    formatin    db  "%d",0
    binary      db  2;used for div
section .text
    global  main
    extern  printf
    extern  scanf
main:
;;; Ask for integer
    push    in_message
    call    printf
    add esp,4       ;remove parameters

    push    integer     ;address of integer where number will be stored
    push    formatin    ;%d parameter, arguments are right to left
    call    scanf
    add esp,8       ;remove parameters

    mov eax,[integer]
    jmp loop
    ;;; terminate if zero
    mov al,1
    mov ebx,0
    int 80h
loop:
    xor edx,edx
    mov ebx,[binary]    ;mov binary to ebx
    div ebx
    push    edx
    push    formatin
    call    printf
    add esp,8
    cmp eax,0       ;compare the quotient with 0;
    jnz loop

【问题讨论】:

  • 你应该做一些调试。

标签: assembly nasm


【解决方案1】:

一个常见的调用约定是将函数调用的返回值放入eax,并且由于printf返回打印的字符数,对于"%d"格式字符串,它通常总是非零(除非你有某种类型的输出失败)。

因此,调用本身可能会将 eax 设置为非零值。

要解决此问题,您需要在调用printf 之前保存eax,然后通过更改来恢复它:

push      edx
push      formatin
call      printf
add esp,  8

进入:

push      eax        ; save here
push      edx
push      formatin
call      printf
add esp,  8
pop       eax        ; restore here

这将确保 printfeax 所做的任何事情都无关紧要,因为您自己保存和恢复它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-08
    • 1970-01-01
    • 2016-11-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-05
    相关资源
    最近更新 更多