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

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是第一个被压入堆栈的,而inout的大小是可变的,我如何访问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 语法。