目录
.SETFRAME 汇编器指令
1. 基本功能
使用具体的寄存器(reg)和偏移(offset)来填充解开信息(unwind information)(即异常处理的机制的相关信息)的寄存器域和偏移域。偏移的大小必须是16的倍数且小于等于240。这个汇编器指令(注意,不是汇编指令)也会为使用当前序言偏移(prologue offset)的具体寄存器产生一个UWOP_SET_FPREG解开数据入口代码。
2. 语法格式
.SETFRAME reg, offset
3. 使用说明
.SETFRAME允许ml64.exe用户指定一个桢函数如何解开(即,当发生异常时,如何从异常环境中还原相应的栈结构并继续向下正常执行其它任务),并且仅允许在序言(prologue)中使用,prologue从桢的声明开始延伸到.ENDPROLOG指令截止。这些汇编器指令不会产生代码;它们仅仅生成.xdata和.pdata。因此,.SETFRAME前面应该前置实际完成解开动作的汇编指令。好的实践方法是将解开指令和它们实际所指的解开代码封包到一个宏中以确保一致性。
4. 示例
; ml64 frmex2.asm /link /entry:frmex2 /SUBSYSTEM:CONSOLE
_text SEGMENT
frmex2 PROC FRAME
push rbp
.pushreg rbp
sub rsp, 010h
.allocstack 010h
mov rbp, rsp
.setframe rbp, 0
.endprolog
; modify the stack pointer outside of the prologue (similar to alloca)
sub rsp, 060h
; we can unwind from the following AV because of the frame pointer
mov rax, 0
mov rax, [rax] ; AV!
add rsp, 060h
add rsp, 010h
pop rbp
ret
frmex2 ENDP
_text ENDS
END
示例说明:
mov rbp, rsp 将当前栈指针存入rbp基指针;.setframe rbp, 0 表明当前栈指针与基地址指针的地址差值为0字节。再比如,有如下两句(STK_LOCAL2为常量):
lea rbp,[rsp+STK_LOCAL2] ;set frame pointer
.setframe rbp,STK_LOCAL2
以上语句表明,当前栈与基址指针之见的位移为STK_LOCAL2个字节。
特别注意:在X64模式下,汇编语言函数可以使用任意非易失性(non-volatile)寄存器作为栈基地址指针,使用RBP寄存器作为基地址指针是为了保持X86_64和遗留X86汇编语言代码之间的一致性。
参考资料:
汇编语言教材:<<Modern X86 Assembly Language Programming>> 2nd Edition,Daniel Kusswurm