ser*_*ncu 7 x86 assembly cpu-registers x86-16
我正在尝试在程序集中创建一个子程序,它将在屏幕上绘制一个正方形.我不认为我可以像在C++中那样将参数传递给子程序,所以我想我可以使用堆栈来存储和访问参数(我不能使用公共数据寄存器,因为有太多变量到通过).
问题是(我记得在某处阅读)当我使用call命令到当前"程序"的地址时,它被保存在堆栈中,因此当它使用"ret"命令时它将知道返回的位置.但是,如果我存储在堆栈上的东西,然后调用函数,我必须保存在某个地方的地址(也就是在堆栈的顶部),然后安全地弹出的参数.然后在代码完成之后并且在调用"ret"之前,我将不得不推回地址.
我对吗?并且,如果是,我在哪里可以存储地址(我不认为地址只有1个字节长,因此它适合AX或BX或任何其他数据寄存器).我可以使用IP来执行此操作(虽然我知道这用于其他事情)?
这就是我的想象:
[BITS 16]
....
main:
mov ax,100b
push ax
call rectangle ;??--pushes on the stack the current address?
jml $
rectangle:
pop ax ;??--this is the addres of main right(where the call was made)?
pop bx ;??--this is the real 100b, right?
....
push ax
ret ;-uses the address saved in stack
Run Code Online (Sandbox Code Playgroud)
Mat*_*lia 11
通常,您使用基指针(bp在16位,ebp在32位上)来引用参数和本地.
基本思想是每次进入函数时都将堆栈指针保存在基本指针内部,以便在函数执行期间将函数作为"固定参考点"调用时使用堆栈指针.在这个模式中,[ebp-something]通常是本地的,[ebp+something]是一个参数.
转置典型的32位,被调用者清理调用约定,你可以这样做:
呼叫者:
push param1
push param2
call subroutine
Run Code Online (Sandbox Code Playgroud)
子程序:
push bp ; save old base pointer
mov bp,sp ; use the current stack pointer as new base pointer
; now the situation of the stack is
; bp+0 => old base pointer
; bp+2 => return address
; bp+4 => param2
; bp+6 => param1
mov ax,[bp+4] ; that's param2
mov bx,[bp+6] ; that's param1
; ... do your stuff, use the stack all you want,
; just make sure that by when we get here push/pop have balanced out
pop bp ; restore old base pointer
ret 4 ; return, popping the extra 4 bytes of the arguments in the process
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
10353 次 |
| 最近记录: |