Reputation: 9703
From what I understand, when a parameter is passed in a function call in C, the callee can find the first parameter at [ebp+8]
.
Returning a value through eax
works for me, reading the right parameter value from the stack doesn't.
Right now I'm just trying to write an assembly function, that can be called from C and returns the same value, that it is being passed.
When I run the following program, it prints number: 1
to the console, no matter what value is passed into myFunc
. What am I doing wrong?
assembly.s
section .text
global _myFunc
_myFunc:
mov eax, [ebp+8]
ret
main.c
#include <stdio.h>
extern unsigned int myFunc(unsigned int somedata);
int main() {
unsigned int i = myFunc(6);
printf("number: %i\n",i);
return 0;
}
I'm using a Mac, nasm to assemble the code and gcc for C compilation.
Makefile
macho32:
nasm -f macho32 assembly.s
gcc -m32 -o macho32 assembly.o main.c
Upvotes: 0
Views: 1793
Reputation: 181
Your function should look like this,
_myFunc:
push ebp ; setup ebp as frame pointer
mov ebp, esp
mov eax, [ebp + 8]
leave ; mov esp,ebp / pop ebp
ret
The convention is to use ebp to access the parameters, to do so you need to save ebp on the stack and make it to point to the new top of the stack. At function exit you should restore ebp and esp, as the leave instruction does.
In nasm there is a macro package, c32.mak, that can help in supporting the C calling convention, these macros are arg, proc and endproc. Using these macros your code should look like,
proc _myfunc
%$i arg
mov eax, [ebp + %$i]
endproc
Upvotes: 1
Reputation: 3820
You need to setup to access the the parameters first by saving esp
. This is explained in:
http://www.nasm.us/doc/nasmdoc9.html
in section "9.1.2 Function Definitions and Function Calls"
The following works for me
assembly.s
section .text
global myFunc:function
myFunc:
push ebp
mov ebp, esp
mov eax, [ebp+8]
mov esp, ebp
pop ebp
ret
main.c
#include <stdio.h>
extern unsigned int myFunc(unsigned int somedata);
int main() {
unsigned int i = myFunc(6);
printf("number: %i\n",i);
return 0;
}
Assembly & Compilation
ericu@eric-phenom-linux:~$ nasm -f elf32 assembly.s
ericu@eric-phenom-linux:~$ gcc -m32 assembly.o main.c
ericu@eric-phenom-linux:~$ ./a.out
number: 6
I am on a linux machine so I use elf32
. The use of macho32
is correct on your Mac.
Upvotes: 2
Reputation: 2541
you refer to argument on stack, by reading from [EBP+offset] - has EBP been set up to actually point at stack? If no, you may have to do that first, conventionally done by:
push ebp
mov ebp,esp
Only then points EBP to its stacked previous contents, below stacked return address, and below passed arguments.
Upvotes: 1