NASM堆栈错误?简单的乘法程序

时间:2013-06-05 17:47:15

标签: c assembly stack nasm

我正在学习NASM,并正在制作一个简单的程序,通过移位和添加来增加任何用户输入变量。

我遇到了一系列问题:由于某种原因,我的被乘数是以一个单词可以容纳的最大数据值给出的。此外,我的答案,如果程序应该到那么远,几乎总是错误的(即使我相信我的算法是正确的!)。

extern printf
extern scanf

section .data
    message: db "Enter your multiplicand: "
    message_L: equ $-message
    message2: db "The number you entered is: %d ", 10, 0
    message2_L: equ $-message2
    message3: db "Enter your multiplier: "
    message3_L: equ $-message3
    message4: db "Your multiplier is: %d ", 10, 0
    message4_L: equ $-message4
    message5: db "The product of this multiplication is: %d ", 10, 0
    mesasge5_L: equ $-message5
    fmt1: db "%d", 0

section .bss
    multiplicand: resw 1
    multiplier: resw 1
    product: resw 1

section .text
    global main
scanInt:
    push ebp
    mov ebp, esp
    sub esp, 2
    lea eax, [ebp-2]
    push eax
    push dword fmt1
    call scanf
    mov ax, word[ebp-2]
    mov esp, ebp
    pop ebp
    ret

main:
    xor eax, eax
    xor ebx, ebx
    xor ecx, ecx
    xor edx, edx

    mov eax, 4
    mov ebx, 1
    mov ecx, message
    mov edx, message_L
    int 80h

        call scanInt
        mov word[multiplicand], ax
    mov word[product], ax

    jmp print1
main2:
    mov eax, 4
    mov ebx, 1
    mov ecx, message3
    mov edx, message3_L
    int 80h

    call scanInt
    mov word[multiplier], ax

    jmp print2
main3:
    mov ax, word[multiplicand]
    jmp check
check:
    cmp word[multiplier], 2
    jz printAnswer
    ror [multiplier], 1
    shl word[multiplier], 1
    jc carry
    shr word[multiplier], 1
    shr word[multiplier], 1
    shl word[product], 1
    jmp check

carry:
    add word[product], ax
    shr word[multiplier], 1
    clc
    jmp check

endLoop:
    mov eax, 1
    mov ebx, 0
    int 80h

printAnswer:
    push ebp
    mov ebp, esp
    push word[product]
    push dword message5
    call printf
    add esp, 12
    mov esp, ebp
    pop ebp
    jmp endLoop

print1:
    push ebp
    mov ebp, esp
    push dword[multiplicand]
    push dword message2
    call printf
    add esp, 12
    mov esp, ebp
    pop ebp
    jmp main2

print2:
    push ebp
    mov ebp, esp
    push dword[multiplier]
    push dword message4
    call printf
    add esp, 12
    mov esp, ebp
    pop ebp
    jmp main3

1 个答案:

答案 0 :(得分:1)

我认为您的主要问题来自于使用word变量。在堆栈上创建一个双字节缓冲区,并调用scanf来读取它几乎肯定是个问题。在32位代码中推送word是“合法的”,但可能会导致问题。在一个实例中,您使用两个变量调用printf,然后调用add esp, 12。将它们全部dword组成,并将堆栈操作保持为四字节块。我认为这将解决你的大多数问题。

手册页明确建议不要将高级缓冲I / O函数与低级函数混合(printfscanffopen()fread(),{ {1}}等是高级函数,fwrite()open()read() ...系统调用是低级函数。我不认为这会导致你的任何问题,但它可能导致奇怪的结果。例如,在刷新缓冲区之前,write()不会打印任何内容。使用换行符结束或使用其他高级I / O功能将刷新缓冲区。例如,printf没有。我会坚持一个或另一个。

祝你好运!