Reputation: 141
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
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