The function in C is
void f(int* out, int* in, int nbElements){
// do stuff
}
Since int nbElements
is the first to be pushed on the stack and in
and out
have variable sizes, how can I access the value of nbElements
?
As far as I understand, the stack looks something like this:
esp
ebp
return address # -4(%ebp)
1st element of int* out # -8(%ebp)
1st element of int* in # (%ebp - 8 - 4*nbElements)
nbElements # not sure how I can access the value of this
So how can I access the value of nbElements
without knowing its address?
The stack frame is somewhat different.
The caller does not set up %ebp
. That is up to the called function, if it choses to use %ebp
at all.
Notice that in your function below, it does not use %ebp
at all. All references to arguments are relative to the stack pointer (%esp
).
This gives the stack frame:
1000: nbElements
0FFE: in
0FFC: out
0FFA: return address
0FF6: <---------------------- %esp points here
So, as below to access nbElements
, you want 12(%esp)
If your function sets up %ebp
, the offsets will change by approx. 4:
.text
.globl f
f:
pushl %ebp
movl %esp,%ebp
movl 8(%ebp), %eax
movl %eax, outsave
movl 12(%ebp), %eax
movl %eax, insave
movl 16(%ebp), %eax
movl %eax, cntsave
pop %ebp
ret
Here is something similar to your function:
int *outsave;
int *insave;
int cntsave;
void
f(int *out, int *in, int nbElements)
{
// do stuff
outsave = out;
insave = in;
cntsave = nbElements;
}
This is the assembly output:
.text
.globl f
f:
movl 4(%esp), %eax
movl %eax, outsave
movl 8(%esp), %eax
movl %eax, insave
movl 12(%esp), %eax
movl %eax, cntsave
ret
This is a sample caller of f
:
void
f(int *out, int *in, int nbElements);
int outbuf[100];
int inbuf[100];
int bufcnt;
void
g(void)
{
f(outbuf,inbuf,bufcnt);
}
This is the assembly for that:
.text
.globl g
g:
subl $16, %esp
pushl bufcnt
pushl $inbuf
pushl $outbuf
call f
addl $28, %esp
ret