Reputation: 767
I am trying to make a simple program in assembler, but I do not understand why, I get a fault. I' ve a 64 bit machine running Ubuntu 12.04, and "as" as a assembly compiler. My goal merely is to print the string "Hello" on screen.
I wrote this:
#print.s
.section .data
.globl StringToPrint
StringToPrint: .asciz "Hello"
.globl _start
_start:
movq $4, %rax
movq $1, %rbx
movq $StringToPrint, %rcx
movq $5, %rdx
int $0x80
_done:
ret
But that's what I get:
$ as print.s -o print.o
$ ld print.o -o print
$ ./print
Hello[1] 10679 segmentation fault (core dumped) ./print
Why do you think this happens? Any idea?
Upvotes: 2
Views: 1575
Reputation: 1191
Here is the fix :
#print.s
.section .data
.globl StringToPrint
StringToPrint: .asciz "Hello"
.globl _start
_start:
movl $5, %edx # string length
movl $StringToPrint, %ecx # pointer to string to write
movl $1, %ebx # file handle (stdout)
movl $4, %eax # system call number (sys_write)
int $0x80 # Passes control to interrupt vector
#sys_exit (return_code)
movl $1, %eax #System call number 1: exit()
movl $0, %ebx #Exits with exit status 0
int $0x80 #Passes control to interrupt vector
As Michael has already said you need to call sys_exit
to avoid segmentation fault .
Edit :
Here is good to mention that int 0x80
invokes 32-bit system calls .
Using int 0x80
for syscall on x64 systems is used for backward compatibility to allow 32-bit applications to run .
On 64-bit systems will be correct to use syscall
instruction .
Here is a working version :
.section .data
StringToPrint: .asciz "Hello"
.section .text
.globl _start
_start:
movq $1, %rax # sys_write
movq $1, %rdi # stdout
movq $StringToPrint, %rsi # pointer to string to write
movq $5, %rdx # string length
syscall
movq $60, %rax # sys_exit
movq $0, %rdi # exit code
syscall
Upvotes: 2
Reputation: 40832
The calling conventions differ between 32 and 64 bit applications in Linux as well as other OSs. Additionally, for Linux the system call numbers are also different. This is how you invoke the write
system call in Linux amd64:
; sys_write(stdout, message, length)
mov rax, 1 ; sys_write
mov rdi, 1 ; stdout
mov rsi, message ; message address
mov rdx, length ; message string length
syscall
Additionally, your application needs to call sys_exit
to terminate, not return using ret
. Read the calling conventions for your platform.
Upvotes: 2