0

所以我试图在汇编程序中创建一个阶乘函数

在 c 中:

 #include<stdio.h>



int fat (int n) 
{
      if (n==0) return 1;
      else return n*fat(n-1);
}

    int main (void){

    printf("%d\n", fat(4));
       return 0;

    }

在装配中:

.text

.global    fat
fat:push    %ebp   
    mov    %esp, %ebp
    movl    $1,%eax
    movl    4(%ebp),%edx

LOOP:cmp    $0,%edx
    je FIM
    sub    $1,%edx
    push    %edx
    call    fat
    imul    %edx,%eax

FIM:mov    %ebp, %esp
    pop    %ebp
    ret

我不断收到分段错误错误,我不知道为什么......有人可以帮助我吗?

4

2 回答 2

2

此行中的偏移量可能是错误的:

movl    4(%ebp),%edx

堆栈已经具有先前的值%ebp和返回地址,因此您的偏移量必须大于 4。

我建议使用调试器单步调试汇编代码,并确保所有寄存器值都与您期望的完全一致。%edx除非您也保存和恢复它的值,否则您还将在调用之间遇到寄存器问题。

于 2012-09-29T21:21:20.240 回答
1
fat:push    %ebp   
    mov    %esp, %ebp
    movl    $1,%eax
    movl    4(%ebp),%edx /* Must be 8(%ebp) because of the return address! */

LOOP:cmp    $0,%edx
    je FIM
    sub    $1,%edx
    push    %edx
    call    fat /* The call to fat() just trashed edx, oops. Gotta save/restore it! */
    imul    %edx,%eax /* The result will be in edx, but you need to return it in eax! */
    /* Why isn't "push %edx" compensated here with "pop" or "addl $4,%esp"??? */
FIM:mov    %ebp, %esp
    pop    %ebp
    ret

重写你的 C 函数,汇编风格,可能会有所帮助:

int fat (int n) 
{
    int eax, edx, savedEdx;

    eax = 1;
    edx = n; /* n = %8(%ebp) */
    if (edx == 0)
      goto done;

    savedEdx = edx; /* can do this with pushl %edx */
    --edx;
    eax = fat(edx); /* pushl %edx; call fat; addl $4, %esp or popl %edx */
    edx = savedEdx; /* popl %edx */

    eax *= edx; /* can do this with imul %edx */

done:
    return eax;
}
于 2012-09-29T21:39:58.327 回答