I am new to assembly language programing, and here I am trying to call C standard library function puts from my assembly code, but I am continuously getting segmentaion fault. Please help; Operating system : LINUX 16.04 Assembler : nasm Machine : intel x86 - 64bit
;comiple and build:
; nasm -f elf64 -F stabs helloc.asm
; gcc -o helloC helloC.o
[SECTION .data]
msg: db "Hello C",0
[SECTION .bss]
[SECTION .text]
extern puts
global main
main:
push rsp
push dword msg
call puts
add rsp,4
pop rsp
ret
to explain Comments More, start with x86 calling convention and your code.
In x86, arguments are located in stack. So basically your function call is x86 way. for example, If you build your code for x86,
[SECTION .data]
msg: db "Hello C",0
[SECTION .bss]
[SECTION .text]
extern puts
global main
main:
push ebp
mov ebp, esp
and esp, 0xfffffff0
sub esp, 0x10
mov DWORD PTR [esp], msg
call puts
mov esp, ebp
pop ebp
ret
It may works fine.
Main difference is two things.
so first, you should change push dword msg
to mov rdi, msg
, and don't clean stack after call (because you didn't push anything to stack)
after change:
[SECTION .data]
msg: db "Hello C",0
[SECTION .bss]
[SECTION .text]
extern puts
global main
main:
push rbp
mov rbp, rsp
and rsp, 0xfffffffffffffff0
mov rdi, msg
call puts
mov rsp, rbp
pop rbp
ret
EDIT: from System V ABI, for call instruction stack be should 16-byte aligned. so push rbp
has effect to alignment, but it is not correct purpose to use. to change that, make stack save logic for both x86 and x86-64.