鉴于前两个参数是动态数组,我如何访问函数最后一个参数的值?
How do I acess the value of the last parameter of a function, given that the first two parameters are dynamic arrays?
C中的函数是
void f(int* out, int* in, int nbElements){
// do stuff
}
由于int nbElements
是第一个被压入堆栈的,而in
和out
的大小是可变的,我如何访问nbElements
的值?
据我了解,堆栈看起来像这样:
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
那么如何在不知道其地址的情况下访问 nbElements
的值?
栈帧有些不同。
调用者不设置%ebp
。这取决于 called 函数,if 它选择完全使用 %ebp
。
请注意,在下面的函数中,它 根本没有 使用 %ebp
。所有对参数的引用都是相对于堆栈指针的 (%esp
)。
这给出堆栈帧:
1000: nbElements
0FFE: in
0FFC: out
0FFA: return address
0FF6: <---------------------- %esp points here
因此,如下访问 nbElements
,您需要 12(%esp)
如果你的函数设置%ebp
,偏移量将改变大约。 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
这是与您的函数类似的内容:
int *outsave;
int *insave;
int cntsave;
void
f(int *out, int *in, int nbElements)
{
// do stuff
outsave = out;
insave = in;
cntsave = nbElements;
}
这是汇编输出:
.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
这是 f
的示例调用者:
void
f(int *out, int *in, int nbElements);
int outbuf[100];
int inbuf[100];
int bufcnt;
void
g(void)
{
f(outbuf,inbuf,bufcnt);
}
这是该程序集:
.text
.globl g
g:
subl , %esp
pushl bufcnt
pushl $inbuf
pushl $outbuf
call f
addl , %esp
ret
不,数组内容没有被复制,只有它们的地址,所以堆栈看起来像(假设从右到左的调用约定,地址从高到低呈现):
nbElements
in
out
return-address
(locals...)
每个参数都有一个相互比较的固定地址(检查 C 调用此类函数的代码以确认这一点)。最后一个参数将位于 ebp+12(假设您已将 push ebp 作为标准序言的一部分完成。
看看 functions and stack frames,尽管您需要转换为 at&t 语法。
C中的函数是
void f(int* out, int* in, int nbElements){
// do stuff
}
由于int nbElements
是第一个被压入堆栈的,而in
和out
的大小是可变的,我如何访问nbElements
的值?
据我了解,堆栈看起来像这样:
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
那么如何在不知道其地址的情况下访问 nbElements
的值?
栈帧有些不同。
调用者不设置%ebp
。这取决于 called 函数,if 它选择完全使用 %ebp
。
请注意,在下面的函数中,它 根本没有 使用 %ebp
。所有对参数的引用都是相对于堆栈指针的 (%esp
)。
这给出堆栈帧:
1000: nbElements
0FFE: in
0FFC: out
0FFA: return address
0FF6: <---------------------- %esp points here
因此,如下访问 nbElements
,您需要 12(%esp)
如果你的函数设置%ebp
,偏移量将改变大约。 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
这是与您的函数类似的内容:
int *outsave;
int *insave;
int cntsave;
void
f(int *out, int *in, int nbElements)
{
// do stuff
outsave = out;
insave = in;
cntsave = nbElements;
}
这是汇编输出:
.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
这是 f
的示例调用者:
void
f(int *out, int *in, int nbElements);
int outbuf[100];
int inbuf[100];
int bufcnt;
void
g(void)
{
f(outbuf,inbuf,bufcnt);
}
这是该程序集:
.text
.globl g
g:
subl , %esp
pushl bufcnt
pushl $inbuf
pushl $outbuf
call f
addl , %esp
ret
不,数组内容没有被复制,只有它们的地址,所以堆栈看起来像(假设从右到左的调用约定,地址从高到低呈现):
nbElements
in
out
return-address
(locals...)
每个参数都有一个相互比较的固定地址(检查 C 调用此类函数的代码以确认这一点)。最后一个参数将位于 ebp+12(假设您已将 push ebp 作为标准序言的一部分完成。
看看 functions and stack frames,尽管您需要转换为 at&t 语法。