LordPaella
LordPaella

Reputation: 141

NASM-64bits-segmentation fault calling procedure

When i run the program i have a segmentation fault. The program consists a simple add between two numbers, store the value in a variable and later print it making a syscall.

Here is the code where i call it:

section .bss
    res: resq 1
    fout: resq 1

section .data
     msg dq 'Hello, world!', 0xa  ;string to be printed
     len equ $ - msg     ;length of the string 
     filename dq 'hello.txt'

section .text
     global _start:     ;must be declared for linker (ld)

_start:             ;tells linker entry point
     mov rcx,5
     mov rdx,4
     call sum
     mov [res],rax

     mov    rdx,1     ;message length
     mov    rcx,res  ;message to write
     mov    rbx,1       ;file descriptor (stdout)
     mov    rax,4       ;system call number (sys_write)
     syscall        ;call kernel

     mov    rax,1       ;system call number (sys_exit)
     syscall       ;call kernel

 sum:
     mov rax,rcx
     add rax,rdx
     add rax,'0'
     ret

Debug info:

 (gdb) n
 sum () at Hello.asm:41
 41              mov rax,rcx
 (gdb) n
 42              add rax,rdx
 (gdb) n
 43              add rax,'0'
(gdb) n
 sum () at Hello.asm:44
 44              ret
 (gdb) n
 0x0000000000000001 in ?? ()
 (gdb) n
 No se pueden encontrar límites en la función actual
 (gdb) quit

The result is a segmentation fault.

Upvotes: 2

Views: 109

Answers (1)

fuz
fuz

Reputation: 92966

You try to store 8 bytes in res with mov [res],rax despite only 1 byte being allotted to res. While this is wrong, this is not the problem that causes your program to fail. Write mov [res], al to fix this.

The real problem is that your system call numbers are wrong. You use the system call numbers for i386 Linux, but these are amd64 system calls which have different numbers. Refer to the values in asm/unistd_64.h for the correct system call numbers. For your example, the correct numbers are 1 for sys_write and 60 for sys_exit. Fixing these numbers makes your program no longer crash, but it still doesn't work correctly.

You also need to fix the registers used. The calling convention for system calls on amd64 is not the same as for i386; you don't put the arguments in ebx, ecx, etc. Instead, you use rdi, rsi, rdx, r10, r8, and r9 as outlined in this answer. Fixing this makes your program finally work.

Upvotes: 2

Related Questions