【问题标题】:Passing parameters on the stack在堆栈上传递参数
【发布时间】:2010-04-09 05:28:21
【问题描述】:

当你将参数传递给 cpu 堆栈上的函数时,

你把参数放在上面,然后 JSR 把返回地址放在堆栈上。 这意味着在您的函数中,您必须获取堆栈的顶部项目(返回地址) 在你可以脱掉其他人之前)

返回值按约定存储在寄存器D0中。

例如以下是正确的方法:

...
|Let’s do some addition with a function,
MOVE.L #4, -(SP)
MOVE.L #5, -(SP)
JSR add
        |the result of the addition (4+5) is in D0 (9)
...

add: 
    MOVE.L   (SP)+,  A1     |store the return address
                            |in a register
    MOVE.L  (SP)+, D0       |get 1st parameter, put in D0
    MOVE.L  (SP)+, D2       |get 2nd parameter, put in D2

    ADD.L      D2, D0       |add them, 
                            |storing the result in D0
    MOVE.L  A1, -(SP)       |put the address back on the 
                            |Stack
    RTS                     |return

【问题讨论】:

    标签: assembly stack motorola 68000


    【解决方案1】:

    您不会从堆栈中“取出”参数,因为您不会弹出它们。您通常分配一个帧寄存器以指向过程入口点处的堆栈顶部,并以常量访问参数,已知帧指针的偏移量。然后你的索引只是“跳过”你知道的返回地址。

    例如在一些假设的装配中,当你在一个程序中时。假设堆栈正在向下增长:

    ...
    argument2
    argument1
    ret addr     <---- stack pointer 
    

    所以只需在偏移量sp+4 访问argument1(假设为32 位),在偏移量sp+8 访问argument2 等。由于这些调用约定是已知的,因此这些偏移量在您的代码中是硬编码的,并且是计算效率高。

    帧指针非常有用,因为您还将局部变量推入堆栈,并且您不希望参数的索引在不同的地方发生变化,因此帧指针在整个过程的执行过程中提供了一个稳定的锚点。

    【讨论】:

      【解决方案2】:

      没有。

      被调用者(目标函数)通常不负责删除自己的参数。调用者将它们放在那里,并且是最知道如何删除它们的人。

      在 68000 上,使用堆栈中的相对偏移量很容易读取,无需从堆栈中物理移除(弹出)参数。这很好地解决了必须“双缓冲”返回地址的问题。

      所以,你的代码应该是这样的:

          MOVE.L #4, -(SP)
          MOVE.L #5, -(SP)
          JSR add
          ADDQ.L #8, SP           |remove the arguments from the stack, both at once.
      
      ...
      
      add: 
          MOVE.L  4(SP), D0       |get 1st parameter, put in D0
          ADD.L   8(SP), D0       |add the 2nd parameter
          RTS                     |return
      

      【讨论】:

        【解决方案3】:

        不,不需要从堆栈中弹出参数来查看它们;通常的程序是使用@eli 所说的“帧指针”寄存器。事实上,68k 甚至有一条指令 (LINK) 旨在促进这一点:它是一条指令,(a) 保存前一个帧指针,(b) 将当前堆栈指针复制到帧指针,以及 (c ) 将堆栈指针递减指定数量,以便为局部变量留出空间。

        这是example of C code and the corresponding 68000 assembler

        【讨论】:

          猜你喜欢
          • 2016-03-17
          • 1970-01-01
          • 1970-01-01
          • 2020-10-31
          • 2011-06-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多