x86程序集递归函数 - >非法指令错误

时间:2015-05-09 18:18:53

标签: assembly x86 nasm

Code1:实现调用fact(factorial)函数的主函数

section .data
    msg db "Enter the Number whose factorial is to be calculated",10,0
    msg1 db "The factorial is: ",0
    ioput db "%d"

section .bss
    a resd 1

section .text
    global main
    extern printf,scanf,fact
main:   
    pusha 
    push msg
    call printf
    add esp,4
    popa

    pusha 
    push a
    push ioput
    call scanf
    add esp,8
    popa

    mov ebx,dword[a]

    pusha
    push ebx
    call fact
    add esp,4


    pusha
    push msg1
    call printf
    add esp,4
    popa

    pusha
    push eax
    push ioput
    call printf
    add esp,8
    popa

    ret

实现事实的Code2(阶乘函数):

section .text
    global fact
    extern printf,scanf
fact:   
    enter 0,0
    cmp ebx,1
    jnz next
    ret

next:
    push ebx
    dec ebx
    call fact
    pop ebx
    mul eax,ebx
    leave
    ret

系统统计:32位机器,Ubuntu 14.04,使用Nasm

问题陈述:程序收到信号SIGILL,非法指令。为什么我会收到此错误?

1 个答案:

答案 0 :(得分:2)

mov ebx,dword[a]

pusha
push ebx
call fact
add esp,4

这是您的程序中存在一些问题的部分!

  1. 您需要初始化EAX以通过调用 fact 获得有意义的结果。一个方便的数字是1。
  2. 由于您使用了pusha,因此您还需要使用popa。我宁愿没有,因为你的代码并不真正需要它。
  3. fact 例程不使用在堆栈上传递的参数。它只是为此目的使用EBX寄存器。这意味着您可以省略push ebxadd esp,4,也可以从事实中删除enterleave说明。
  4. 这是您可以编写以解决所有问题的代码。

    mov ebx,dword[a]
    mov eax,1
    pusha
    call fact
    mov [esp+28],eax
    popa
    

    较短的版本是

    mov ebx,dword[a]
    mov eax,1
    call fact