Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly NASM中的堆栈问题_Assembly_Stack_Nasm - Fatal编程技术网

Assembly NASM中的堆栈问题

Assembly NASM中的堆栈问题,assembly,stack,nasm,Assembly,Stack,Nasm,我正在用NASM编写一个程序,计算斐波那契序列并打印出来。它接受用户输入的两个种子值和迭代次数,将它们存储在堆栈上,然后调用“fib”子例程进行计算和打印。我正在使用来自的库来执行诸如读取输入/打印之类的操作 这是我的asm_main: asm_main: enter 0,0 ; setup routine pusha mov eax, prompt1 ; access first prompt

我正在用NASM编写一个程序,计算斐波那契序列并打印出来。它接受用户输入的两个种子值和迭代次数,将它们存储在堆栈上,然后调用“fib”子例程进行计算和打印。我正在使用来自的库来执行诸如读取输入/打印之类的操作

这是我的asm_main:

asm_main:
        enter   0,0                 ; setup routine
        pusha

    mov eax, prompt1        ; access first prompt
    call    print_string        ; print prompt
    call    read_int        ; read input and stores in eax
    push    eax         ; store input on stack

    mov eax, prompt2        ; access second prompt
    call    print_string        ; print prompt
    call    read_int        ; read input and stores in eax
    push    eax         ; store input on stack

    mov eax, prompt3        ; access third prompt
    call    print_string        ; print prompt
    call    read_int        ; read input and stores in eax
    push    eax         ; store input on stack

    call    fib         ; call fib subroutine to calculate sequence
    call    print_nl        ; end with a newline
下面是fib子程序:

fib:
    pop ecx         ; retrieve number of iterations from stack
    pop ebx         ; retrieve second seed value from stack
    pop eax         ; retrieve first seed value from stack

    _looper:            ; section to be looped
        mov edx, eax
        add edx, ebx    ; sum = a + b
        call    print_int
        call    print_nl
        mov eax, ebx    ; a = b
        mov ebx, edx    ; b = sum
        loop _looper
    ret
然而,这种推和弹出的方式不能正常工作,我不明白为什么。当我输入“3”作为第一个种子值,“5”作为第二个种子值,“7”作为迭代次数时,以下是在fib中调用的寄存器转储的结果:

Register Dump # 1
EAX = 00000005 EBX = 00000007 ECX = 080484D4 EDX = BF97A1B4
ESI = 00000000 EDI = 00000000 EBP = BF97A168 ESP = BF97A144
EIP = 08048480 FLAGS = 200282       SF 

我是不是遗漏了什么?根据我的理解,堆栈应该是后进先出的,我无法找出哪里出了问题。谢谢

当您
呼叫fib
时,在
fib
内部,您将从堆栈中弹出的第一个内容是返回地址。只要您确保在弹出参数后将其推回打开状态,则可以取消该选项,否则最后的
ret
指令会将您发送到您不希望的地方

例如,你可以这样做

fib:
    pop edx         ; pop return address
    pop ecx         ; retrieve number of iterations from stack
    pop ebx         ; retrieve second seed value from stack
    pop eax         ; retrieve first seed value from stack
    push edx        ; put return address back on stack
    ...
但更传统的方法是使用

    push ebp
    mov ebp, esp
然后使用

    mov ecx, [ebp+8]
    mov ebx, [ebp+12]
等等

然后弹出堆栈框架和结尾的参数:

    mov esp, ebp
    pop ebp
    ret 12
后一种方法允许您在需要时访问参数,而不仅仅是在进入例程时