NASM - The Netwide Assembler
NASM Forum => Programming with NASM => Topic started by: clzola on March 13, 2014, 01:41:39 PM
-
I wrote this code ant it gives me "Segmentation fault (core dumped)" after I input a number.
test.asm
%include "asm_io.inc"
extern printf
global asm_main
section .data
msg db "Value: %d",10,0
section .text
asm_main:
enter 0, 0
pusha
call read_int ; this function is from asm_io.asm
; It reads an integer and stores it in EAX register.
push msg ; switching next two lines prints message on screen with correct value
push eax ; but still getting Segmentation fault error.
call printf
popa
mov eax, 0
leave
ret
driver.c
int main()
{
int ret_value;
ret_value = asm_main();
return ret_value;
}
asm_io.inc and asm_io.asm are files provided with book PC Assembly Language. I am trying to use printf function as I would do it in C.
printf("Value: %d", x); // this x should be in eax.
to compile: (Linux x86)
nasm -f elf test.asm
gcc asm_io.o test.o driver.o -o test
-
Hi!
Try this, maybe works:
%include "asm_io.inc"
extern printf
global asm_main
section .data
msg db "Value: %d",10,0
section .text
asm_main:
enter 0, 0
pusha
call read_int ; this function is from asm_io.asm
; It reads an integer and stores it in EAX register.
push eax
push msg
call printf
add esp,2*4
popa
mov eax, 0
leave
ret
-
Yes. It works.
Why do I need that "add esp, 2*4"?
-
You need to understand what is calling convetions,
that was the error in this case.
In this case it was CDECL, because printf used CDECL calling convention,
and you need to clear stack for every variable you pushed onto stack, before
you called printf, read more here:
Wiki: x86 calling conventions - CDECL (http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl)
Wiki: x86 calling conventions - Caller clean-up (http://en.wikipedia.org/wiki/X86_calling_conventions#Caller_clean-up)
-
Yes. It works.
Why do I need that "add esp, 2*4"?
You pushed two times before you called printf.
push eax
push msg
call printf
printf is CDECL, so you need to restore or pop pushed items of the stack.
1. Restore stack pointer after CDECL procedure like printf was called:
add esp, 2*4
OR this also should do the trick, if eax is not needed:
2. Restore stack pointer after CDECL procedure like printf was called:
pop eax
pop eax
OR
3. Restore stack pointer after CDECL procedure like printf was called:
add esp,4
add esp,4
* Error in early code was caused because you didn't knew that printf is CDECL.
So, read, find info about x86 calling convetions (CDECL/STDCALL/Other) or use my links above.
Bye!
-
Thank you, I understand now.