Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

calling assembly functions from c

People also ask

How do you call a function in assembly?

To call an external function, such as NetRun's "print_int", or a standard C library function like "exit", you need to tell the assembler the function is "extern". "extern" isn't actually an instruction--it doesn't show up in the disassembly--it's just a message to the assembler, often called a pseudoinstruction.

Can you run assembly in C?

We can write assembly program code inside c language program. In such case, all the assembly code must be placed inside asm{} block.

What is __ asm in C?

The __asm keyword invokes the inline assembler and can appear wherever a C or C++ statement is legal. It cannot appear by itself. It must be followed by an assembly instruction, a group of instructions enclosed in braces, or, at the very least, an empty pair of braces.

How is C compiled to assembly?

The compiler takes the preprocessed file and uses it to generate corresponding assembly code. Assembly code, or assembly language (often abbreviated asm), is a high-level programming language that corresponds programming code with the given architecture's machine code instructions.


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

Further explanation:

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.

Update:

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

Update 2:

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.