views:

246

answers:

3

In assembler:

.globl _test

_test:

pushl %ebp
movl %esp, %ebp
movl 8(%ebp), %eax

pushl %eax
call printf

popl %ebp
ret

Calling from c

main()
{
  _test("Hello");
}

Compile:

gcc -m32 -o test test.c test.s

This code gives me illegal instruction sometimes and segment fault other times. In gdc i always get illegal instruction, this is just a simple test, i had a larger program that was working and suddenly after no apperant reason stopped working, now i always get this error even if i start from scratch like above.

I have narrowed it down to pushl %eax & call printf, if i comment out those lines the code runs fine.

Any ideas? (I'm running the program at my universities linux cluster, so I have not changed any settings..)

+3  A: 

Your last two instructions corrupt the stack base pointer. Any code relying on ebp (the base pointer) to point to actual stack space will fail. Usually expecting ebp to point to stack space is a safe assumption, and you shouldn't invalidate that assumption when interfacing with C-code.

You are doing pushl %eax (or any other register) and then doing popl %ebp. These two together have the same effect as doing movl %eax, %ebp.

I assume you are trying to return the value stored in eax. In C calling convention, eax is used for return values so there's no need to push it or do anything with it, just leave the value in it and the other code will pick it up. If that's not what you are trying to do, then I'm stumped as to why you would be pushing %eax at the end of this function.

SoapBox
Thanks for pointing that out, i update the main post with a more sane sample, i still get the error though.printf pops the last item of the stack so popl ebp should be correct now.
Bernt
The code is still wrong - the *caller* is responsible for popping arguments, not the callee. Your function epilogue should be `movl %ebp, %esp` `popl %ebp`, not just the `popl %ebp`.
caf
+2  A: 

Replace the pop instruction with leave. This restores the stack- and base pointer.

Hofstad
A: 

this whole asm code looks weird, is main int() type? int main()? what is the calling convention for _test()?

Bartosz Wójcik
@Bartosz, in C, functions without a return-type implicitly return "int", while in C++, the "main()" is permitted as a signature for main.
Michael Aaron Safyan