Assembly 如果前两个参数是动态数组,如何访问函数最后一个参数的值?
C中的函数是Assembly 如果前两个参数是动态数组,如何访问函数最后一个参数的值?,assembly,x86,gnu-assembler,calling-convention,att,Assembly,X86,Gnu Assembler,Calling Convention,Att,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
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
。这取决于被调用函数,如果它选择使用%ebp
请注意,在下面的函数中,它根本不使用%ebp
。对参数的所有引用都与堆栈指针相关(%esp
)
这将提供堆栈帧:
1000: nbElements
0FFE: in
0FFC: out
0FFA: return address
0FF6: <---------------------- %esp points here
下面是与您的函数类似的内容:
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 $16, %esp
pushl bufcnt
pushl $inbuf
pushl $outbuf
call f
addl $28, %esp
ret
不,不复制数组内容,只复制它们的地址,因此堆栈将如下所示(假设从右向左调用约定,地址从高到低显示):
每个参数都有一个彼此比较的固定地址(检查C调用此类函数的代码以确认这一点)。最后一个参数将在ebp+12(假设您已将推ebp作为标准开场白的一部分完成)
看一看,尽管您需要转换为at&t语法。您的指针大小可变?我的意思是,当然,这不是大小重要的情况:)是的,没关系,我想我把堆栈和堆搞混了。。。所以nbElements是-16(%ebp),对吗?in
和out
没有可变的大小。它们是指针,所以每个是4字节,句点。它们指向的数组的大小是可变的,但该数组不会传递到堆栈上,因此堆栈布局不受此影响。
.text
.globl g
g:
subl $16, %esp
pushl bufcnt
pushl $inbuf
pushl $outbuf
call f
addl $28, %esp
ret
nbElements
in
out
return-address
(locals...)