Lyn*_*ite 4 assembly stack 68000 motorola
将参数传递给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
Run Code Online (Sandbox Code Playgroud)
从没有弹出它们的意义上讲,你不会从堆栈中"取消"参数.您通常会在程序的入口点指定一个帧寄存器指向堆栈的顶部,并从帧指针的常量已知偏移量访问参数.然后你的索引只是"跳过"你知道的返回地址.
例如,在一些假设的装配中,当你在一个程序中.假设堆栈正在增长:
...
argument2
argument1
ret addr <---- stack pointer
Run Code Online (Sandbox Code Playgroud)
因此,只需访问argument1偏移量sp+4(假设为32位),argument2偏移量sp+8等.由于这些调用约定是已知的,因此这些偏移量在代码中是硬编码的,并且计算效率很高.
帧指针非常有用,因为您还将局部变量推送到堆栈,并且您不希望在不同位置更改参数的索引,因此帧指针在整个过程执行期间提供稳定的锚点.
没有.
被调用者(目标函数)通常不负责删除自己的参数.呼叫者把它们放在那里,并且是最了解如何移除它们的人.
在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
Run Code Online (Sandbox Code Playgroud)