C程序如何在引擎盖下传递参数?

CCN*_*CNA 1 c assembly stack compilation pdp-11

这是PDP-11代码混合C和汇编.在下面,u.u_rsav是一个数组指针,

savu(u.u_rsav);

该函数的汇编代码是

_savu:        bis     $340,PS
              mov     (sp)+,r1
              mov     (sp),r0
              mov     sp,(r0)+
              mov     r5,(r0)+
              bic     $340,PS
              jmp     (r1)
Run Code Online (Sandbox Code Playgroud)

看起来在进入程序之前,它首先推送参数,然后推送返回点PC值.因此,r1存储PC,r0存储参数.我的谜题是sp(堆栈指针)在汇编代码跳回调用点之前不会恢复到原始值.它仍然指向参数存储在堆栈中的位置.

Jer*_*myP 6

在C中,特别是任何PDP-11编译器可能使用的K&R C,被调用函数无法知道调用函数在堆栈上放置了多少个参数.这就是var args函数用于工作的方式.例如,printfstdio.h像这样声明:

int printf();
Run Code Online (Sandbox Code Playgroud)

定义将从这样开始:

int printf(fmt)

char *fmt;

{
    /* function body */
}
Run Code Online (Sandbox Code Playgroud)

然后调用者就可以这样做(例如)

printf("%d %d\n", a, b);
Run Code Online (Sandbox Code Playgroud)

因此,调用函数必须从堆栈中删除参数,而不是被调用的函数.

为了使事情更清晰,并且它不仅仅是可变函数,在K&R C中,以下是完全合法的并且将打印3.

int add();

int main()
{
    int sum;
    sum = add(1, 2, 3, 4);
    printf("%d\n", sum);
    return 0;
}

int add(a, b)
int a;
int b;
{
    return a + b;
}
Run Code Online (Sandbox Code Playgroud)