汇编网首页登录博客注册
masmaster的学习博客
博客首页博客互动【做检测题】论坛求助

我的博客

个人首页 |  我的文章 |  我的相册 |  我的好友 |  最新访客 |  文章收藏 |  论坛提问 |  友情链接 |  给我留言  
图片载入中
文章收藏

[2010-07-31 10:08] 关于堆栈框架(3)

通过堆栈传递8位和16位参数:
在保护模式下传递堆栈参数时,最好使用32位的操作数,虽然可以在栈中压入16位的操作数, 但是这样做会使ESP无法对齐在双字地址边界上,有此可能导致页故障,程序的性能也可能降低。 因此在传递8位或16位堆栈参数时,利用指令movzx把它扩展成32位模式后再压入。例如:
var1 db x
var2 dw y
...
movzx eax,var1
push eax
movzx eax,var2
push eax
call ...

传递长整数参数:
在使用堆栈向过程传递长整数(由多个字节构成)参数时, 可以先把高位字节压入, 然后再把低位字节 压入,这样实际上是以小尾顺序(低地址在低地址高地址在高地址)把场整数入栈了。例如:
longvar dq 1234567890abcdefh
...
push dword ptr longvar+4
push dword ptr longvar
call ...

保存和恢复寄存器:
子例程通常在修改寄存器之前保存其原来的值, 以便在过程返回之前进行恢复。 理想的情况下,要保存的寄存器应在EBP设为ESP的值后,为局部变量保留空间之前压入堆栈, 这有助于避免改变堆栈参数的相对偏移。例如:
subproc    proc
           push ebp         ;保存基址指针
           mov ebp,esp      ;堆栈基址
           push ecx         ;压入ecx和edx
           push edx
           mov eax,[ebp+8]  ;获取堆栈参数
           ...              ;过程操作
           pop edx          ;恢复已保存的寄存器
           pop ecx          ;ecx和edx
           pop ebp          ;恢复基址指针
           ret              ;返回
subproc    endp
EBP在初始化以后, 在整个过程中其值保持不变,ecx和edx的入栈不影响栈中的参数相对于EBP的偏移。这是因为,堆栈是向下增长的, 见图:
-----------------
|    堆栈参数   | [EBP+8]
-----------------
|    返回地址   | [EBP+4]
-----------------
|    EBP        |  EBP
-----------------
|    ECX        |
-----------------
|    EDX        |  <--ESP,SS:ESP时刻指向栈顶
-----------------

USES对堆栈的影响:
uses操作符后跟要在过程开始时保存并在过程结束时恢复的寄存器列表。对于uses后的每个寄存器, masm自动生成合适的push和pop指令。
注意: 使用显式堆栈参数的过程应避免使用uses操作符。这是因为由于masm在过程的开始插入了push指令, 因此改变了堆栈参数对于EBP的偏移, 进而导致发生错误哦。
评论次数(0)  |  浏览次数(367)  |  类型(汇编语言笔记) |  收藏此文  | 
 
 请输入验证码  (提示:点击验证码输入框,以获取验证码