Создание и вызов функции в сборке x86 (синтаксис AT&T)

Пожалуйста, дайте мне очень простой пример создания функции и вызова ее на ассемблере x86 (синтаксис AT&T). На самом деле я пытаюсь создать функцию, которая вычисляет factorial числа. Это все, что я сделал:

#include<syscall.h>
#include<asm/unistd.h>
# Calculates Factorial, Argument is passed through stack
.text
.global _start
_start:
    pushl $5       #factorial of this value will be calculated
    call Fact
    movl %eax, %ebx #eax contains the result, Result is the return val of the program
    movl $1, %eax
    int $0x80
    ret
Fact:
    popl %ebx     #Return address
    popl %edx
    movl $1, %ecx #Will be used as a counter
    movl $1, %eax #Result(Partial & complete) will be stored here
    LOOP:
        mul %ecx
        inc %ecx
        cmp %ecx, %edx
        jle LOOP
    pushl %ebx    #Restore the return address
    ret

Я снова и снова получаю сообщение об ошибке Segmentation Fault. Я использую GAS на Ubuntu.


person batman    schedule 03.09.2012    source источник


Ответы (1)


Ваш код не должен падать. Убедитесь, что вы собрали и слинковали как 32 бита:

as --32 -o x.o x.s
ld -melf_i386 -o x x.o

Однако код неверный. Особенно:

  • 'mul %ecx' изменяет %edx
  • аргументы 'cmp' должны быть обратными

Вот исправленная версия:

        .text
        .global _start
_start:
        pushl $5
        call fact
        addl $4, %esp

        movl %eax, %ebx
        movl $1, %eax        # sys_exit
        int $0x80

fact:
        movl 4(%esp), %ecx
        movl $1, %eax
1:
        mul %ecx
        loop 1b
        ret

Запустите его с помощью:

./x; echo $?
person Community    schedule 03.09.2012