子程序调用后未使用变量的值发生变化 - 汇编

时间:2017-04-15 04:46:08

标签: gcc assembly nasm

我对过去7个小时里学习的大会很陌生(这是我下个学期从下个月开始学习的课程)。我阅读了一些在线教程和nasm手册,并开始将一个C程序移植到nasm,仅用于学习。

int fact(int n)
{
    return (n < 0) ? 1 : n * fact(n - 1);
}

然后我开始将它移植到程序集中,并将其作为我的解决方案:

fact:
    ; int fact(int n)
    cmp dword ebx, 0    ; n == 0
    je .yes
.no:
    push ebx            ; save ebx in stack
    sub  ebx, dword 1   ; sub 1 from ebx. (n - 1)
    call fact           ; call fact recursively
    pop  ebx            ; get back the ebx from stack
    imul eax, ebx       ; eax *= ebx; eax == fact(n - 1)
    ret
.yes:
    mov eax, dword 1    ; store 1 in eax to return it
    ret

我在ebx寄存器中接受一个DWORD(我想假设)并返回eax寄存器中的值。正如您所看到的,我根本没有使用我在i部分声明的变量.bss。我的变量是这样的:

section .bss
    ; int i, f
    i resb 2
    f resb 2

对于一个int,它是2个字节吗?好的,然后我在_main中提示用户,使用_scanf获取输入,然后调用该函数。除此之外并调用函数,我没有其他代码可以更改i变量的值。

    mov ebx, dword [i]  ; check for validity of the factorial value
    cmp dword ebx, 0
    jnl .no
.yes:
    push em             ; print error message and exit
    call _printf
    add esp, 4
    ret
.no:
    push dword  0       ; print the result and exit
    push dword [i]
    push rm
    call _printf
    add esp, 12

    call fact           ; call the fact function
    mov dword [f], eax

    push dword [f]      ; print the result and exit
    push dword [i]
    push rm
    call _printf
    add esp, 12
    ret

我没有看到我正在修改i变量的值,在调用fact之前的第一次打印时,它确实是用户输入的相同值,但在调用之后函数,在后面的打印中,它打印一些垃圾值,如下面的输出:

E:\ASM> factorial
Enter a number: 5
The factorial of 5 is 0The factorial of 7864325 is 120
E:\ASM>

任何线索?我的完整源代码在这个要点:https://gist.github.com/sriharshachilakapati/70049a778e12d8edd9c7acf6c2d44c33

0 个答案:

没有答案