Assembly 如果前两个参数是动态数组,如何访问函数最后一个参数的值?

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

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
。这取决于被调用函数,如果它选择使用
%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...)