-1

我目前正在学习 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
4

1 回答 1

1

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

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

祝你好运!

于 2013-06-05T19:54:48.693 回答