曲径通幽论坛

标题: 堆栈相关指令 [打印本页]

作者: beyes    时间: 2009-12-6 16:33
标题: 堆栈相关指令
1、压栈指令 -- PUSH

PUSH 指令的格式是:
pushx source
其中,source 是要放入堆栈的数据元素。x 是一个字符的代码,表示数据长度,和 MOV 指令中所用是一样的格式,但 PUSH 指令只能对 16 位和 32 位数据值进行操作:

可以对其进行 PUSH 操作的数据元素如下:
长度代码必须和指令中声明的数据元素匹配,否则发生错误。PUSH 的用法如:
pushl %ecx
pushw %cx
pushl $100
pushl data
pushl $data
上面,注意使用标签 data 和内存位置 $data 之间的区别。data 表示把内存中包含的数据值存放到堆栈中,而 $data 则是把内存地址存放到堆栈中。

2、出栈指令 -- POP

POP 指令的格式是:
popx destination
其中, x 和 push 指令中的 x 一样,表示的是数据元素的长度。通过 POP 指令可以使下面的数据元素接收数据:
POP 指令用法如:
popl  %ecx
popw %cx
popl   value

3、压入和弹出所有寄存器
对于同时快速地设置和获得所有通用寄存器的当前状态,PUSHA 和 POPA 指令非常有用。
PUSHA 指令压入 16 位寄存器,使它们按照 DI, SI, BP, BX, DX, CX 最后是 AX 的顺序出现在堆栈中。
PUSHAD 指令按照相同的顺序,把这些寄存器对应的 32 位寄存器压入堆栈。
POPA 和 POPAD 指令按照压入寄存器的相反顺序获得寄存器状态。

指令
描述
PUSHA/POPA
压入或者弹出所有16位通用寄存器
PUSHAD/POPAD
压入或者弹出所有32位通用寄存器
PUSHF/POPF
压入或者弹出 EFLAGS 寄存器的低16位
PUSHFD/POPFD
压入或者弹出EFLAGS 寄存器的全部32位

POPF 和 POPFD 指令的行为因处理器的操作模式不同。当处理器运行在保护模式下的 ring 0 (特权模式) 下时,EFLAGS 寄存器中的所有非保留标志都可以被修改,除 VIP, VIF 和 VM 标志外。

PUSH 和 POP 不是把数据压入和弹出堆栈的唯一途径。也可以通过使用 ESP 寄存器作为内存指针,手工地把数据放到堆栈中。通常,会看到许多程序把 ESP 寄存器的值复制到 EBP 中,而不是使用 ESP 寄存器本身。在汇编语言函数中,经常使用 EBP 指针指向函数的工作堆栈空间的基址,然后使用相对于 EBP 的偏移来访问存储在堆栈中的参数。




欢迎光临 曲径通幽论坛 (http://www.groad.net/bbs/) Powered by Discuz! X3.2