Search code examples
assemblyx86gnu-assembleratt

Creating and calling function in x86 assembly (AT&T syntax)


Please give me a very simple example of creating a function and calling it in x86 Assembly (AT&T syntax). Actaully I am trying to create a function that computes factorial of a number. This is what all I did :

#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

I am getting Segmentation Fault error, again and again. I am using GAS on Ubuntu.


Solution

  • Your code shouldn't crash. Make sure you assemble and link as 32 bits:

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

    The code is incorrect however. In particular:

    • 'mul %ecx' alters %edx
    • the arguments to 'cmp' must be reversed

    Here is a corrected version:

            .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
    

    Run it with:

    ./x; echo $?