I’m trying to use a function in assembly, invoked from a C project. This function is supposed to call a libc function let’s say
printf(), but I keep getting a segmentation fault.
In the .c file I have the declaration of the function let’s say
In the .asm file I have
.extern printf .section .data printtext: .ascii "test" .section .text .global do_shit_in_asm .type do_shit_in_asm, @function do_shit_in_asm: pushl %ebp movl %esp, %ebp push printtext call printf movl %ebp, %esp pop %ebp ret
pointers comments would be appreciated.
as func.asm -o func.o gcc prog.c func.o -o prog
push printtext to
As it is, you’re loading a value from the address
printtext and pushing that, rather than pushing the address. Thus, you’re passing
'test' as a 32-bit number, rather than a pointer, and
printf is trying to interpret that as an address and crashing.
One of the best ways to get started with assembly language functions is to write a similar function in C, and then build it with the compiler switch that generates an assembly listing (
-S on gcc). Then you can study the output of what the compiler did, and modify as needed.
This is particularly useful if you’re calling functions such as
printf which use a different calling convention (because of the variable number of arguments). Calling those functions may be quite different from calling non-varargs functions.
the issue was that i was using
Thanks everybody for your help and sorry for wasting your time 😛
push printtext call printf
addl $4, %esp
Because you’re using x86 Linux I assume the calling convention requires the callee to cleanup the parameters. Because you pushed a pointer before calling
printf, your stack is off by 4 after that function’s
ret instruction happened.
Yeah, OK, I was used to Intel syntax so I was getting the order of the arguments backward in my head. Actually the lack of the
addl back to
esp doesn’t matter, because you’re restoring
esp correctly near your
ret. My next guess is that the string you’re passing to
printf is lacking a null terminator… Let me see what
gas null terminates strings for you, so I guess my second hunch was wrong. It looks like you found the issue so the point is moot.