简体   繁体   中英

calling assembly functions from c

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

int do_shit_in_asm()

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

Any pointers comments would be appreciated.

as func.asm -o func.o

gcc prog.c func.o -o prog

Change push printtext to push $printtext .

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

pushl printtext

rather that

pushl $printtext

Thanks everybody for your help and sorry for wasting your time :P

After this:

push printtext
call printf

You want:

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 does...

OK, 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM