Assembly 在汇编编程中,如何将方法的结果传递回堆栈?

Assembly 在汇编编程中,如何将方法的结果传递回堆栈?,assembly,stack-machine,Assembly,Stack Machine,这是汇编代码: ldc 5 // a ldc 12 // b bsr sumsquare ajs -2 // delete parameters ldr RR // result on the stack stl 1 // store in a variable .... sumsquare: link 1 // 1 local variable ldl -3 // a ldl -3 // a mul

这是汇编代码:

    ldc 5 // a
    ldc 12 // b
    bsr sumsquare
    ajs -2 // delete parameters
    ldr RR // result on the stack
    stl 1 // store in a variable
    ....
    sumsquare:
    link 1 // 1 local variable
    ldl -3 // a
    ldl -3 // a
    mul // a*a
    ldl -2 // b
    ldl -2 // b
    mul // b*b
    add // a*a + b*b
    stl 1 // x
    ldl 1 // x
    str RR // store in RR (=result register)
    unlink 1
    ret

我希望以这样一种方式更改这段代码,即将方法sumsquare的结果传递回堆栈。如果我是对的,我所要做的就是不把它存储在RR上,而是把它立即存储在堆栈上,变量a和b在堆栈中。所以我必须用别的东西来代替str-RR

指令集
调用者先按
5
,然后按
12
,然后按返回地址,然后将控制权转移到
sumsquare
,它在MP-3(实际值
5
)处使用形式参数
a
,在MP-1返回地址后面的堆栈上,在MP-2(实际值
12
)处使用形式参数
b
。从被调用者返回到调用者会将返回地址从堆栈中弹出,将实际参数
5
12
留在堆栈中,然后调用者会将其从堆栈中弹出

至少有三种可能的方法:

一种方法是让被调用方(函数)在函数结束时重新调整第一个形式参数的用途,方法是将返回值存储到-3处的形式参数
a
,然后让调用方只弹出堆栈中的第二个实际参数,而不是两个实际参数,在堆栈上留下一个正常使用的返回值(即通过表达式计算,例如通过算术或赋值)。这种方法需要对零参数函数进行特殊处理

下一种方法是传递一个为返回值保留空间的伪参数。在
5
12
之前,首先传递伪参数。被调用方不将返回值存储到-3处的形式参数
a
a,而是将其存储到-4处的伪参数。然后,调用方将根据原始值将实际参数
5
12
从堆栈中弹出(但通常使用现在持有返回值的伪参数)。这种方法的优点是更规则(允许零参数函数与所有其他函数一样工作)

另一种方法是更改调用约定,以便被调用方(函数)从堆栈中删除自己的形式参数,只在堆栈上留下返回值。为此,它必须(1)将返回值存储在形式参数
a
at-3处,然后(2)将返回地址从其当前位置-1移动到
b
at-2处,然后(3)将返回地址的旧副本从堆栈中弹出,并返回给调用方(从堆栈中弹出返回地址(aka
b
)的新副本,只在堆栈中保留返回值)。在此场景中,调用者不会弹出实际参数,这是被调用者所做的。此表单要求函数在结束时做一些工作,但可以节省调用站点的空间;这可以通过观察函数调用通常多于函数本身来合理化(函数由多个调用者调用)。(有时会提供特殊的堆栈指令来更直接地执行此操作。)但是,这种形式不利于varargs()(如果不知道任何给定函数是否可以是可变的,则这种形式将不可行)


对于表达式求值和函数链接共享一个堆栈,这种洗牌是必要的

在不同的体系结构中,两个独立的堆栈将允许在表达式堆栈上留下一个返回值,同时仍然能够弹出链接以返回给调用者——尽管两个堆栈会给硬件增加其他开销


在另一种体系结构方法中,将有一个寄存器或累加器,这就是返回值的位置。

请不要随意发送标签。我已经删除了不适用的标签。这是CIL中间代码吗?如果不是,您需要提供机器的规格。如果没有kno,就无法回答您的问题wing机器如何工作。感谢您的更新。我已经调整了标记,因为这似乎不是CIL。要解决您的问题:在程序中的任何给定时间可视化堆栈上的内容。
ret
指令从堆栈中获取返回地址,因此在它之前,堆栈顶部必须是返回地址和s堆栈的第二个值必须是要返回的值。请尝试找出如何将堆栈重新排列以达到此状态。如果您找不到解决方案,请告诉我,以便我可以进一步帮助您。这似乎是一个用于演示架构课程的堆栈机器:“如果我是对的,我所要做的就是不将其存储在RR上,而是立即将其存储在堆栈上”:在
ret
之前,将返回地址弹出到某个备用寄存器中,按下您的值,然后按下打包返回地址。如果允许覆盖传递的参数,则使用“stl-2”