【问题标题】:NASM Stack Error? Simple Multiplication ProgramNASM 堆栈错误?简单的乘法程序
【发布时间】:2013-06-05 17:47:15
【问题描述】:

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

【问题讨论】:

  • 为什么不把代码放在这里呢?我公司的防火墙不允许我访问 pastebin。 >8v(
  • 它工作正常吗?它具体做错了什么?

标签: c assembly stack nasm


【解决方案1】:

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

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

祝你好运!

【讨论】:

    猜你喜欢
    • 2013-08-13
    • 1970-01-01
    • 1970-01-01
    • 2013-09-30
    • 1970-01-01
    • 2023-03-14
    • 2012-10-19
    • 1970-01-01
    • 2013-04-16
    相关资源
    最近更新 更多