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

时间:2018-03-14 14:51:44

标签: c assembly compilation stack 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)

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

2 个答案:

答案 0 :(得分:6)

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

int printf();

定义将从这样开始:

int printf(fmt)

char *fmt;

{
    /* function body */
}

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

printf("%d %d\n", a, b);

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

为了使事情更加清晰,并且不仅仅是可变函数,在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;
}

答案 1 :(得分:0)

它不是C,而是Application Binary Interface约定(你经常有几个语言实现或编译器跟在相同的 ABI之后,你确实在过去在同一系统上使用不同的 ABI约定的各种编译器。它是特定于体系结构和操作系统的。 BTW,calling conventions是ABI的一部分。

例如,请参阅related to x86

您可以自行查找考古PDP11计算机(以及编译器和操作系统)的ABI约定,例如:见PDP11 FAQC calling conventions。一些ABI使用堆栈,在寄存器上有各种调用者安全/被调用者安全约定。

  

我的谜题是sp(堆栈指针)在汇编代码跳回到调用点之前没有恢复到原始值。

某些ABI或调用约定要求被调用函数恢复堆栈指针。其他人希望调用函数能够做到这一点。