分组装配NASM后的无限循环

时间:2014-10-19 09:19:15

标签: assembly nasm

我试图在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

1 个答案:

答案 0 :(得分:1)

一个常见的调用约定是将函数调用的返回值放入eax,并且由于printf返回打印的字符数,因此{{1}通常总是非零格式化字符串(除非您有某种类型的输出失败)。

因此,呼叫本身可能会将"%d"设置为非零值。

要解决此问题,您需要在调用eax之前保存eax,然后通过更改以下内容将其恢复:

printf

成:

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 printf所做的任何事都无关紧要,因为您自己保存并恢复它。

相关问题