Masm64:堆栈与堆栈指令PUSH/POP

一、堆栈(Stack)的概念

1. 定义

在MASM64中,堆栈是一种特殊的数据结构,用于临时存储数据。它遵循后进先出(LIFO - Last In First Out)的原则,就像一摞盘子,最后放上去的盘子最先被拿走。

2. 用途

保存函数调用时的返回地址、参数、局部变量等信息。在程序执行过程中,当需要暂时保存数据以便后续恢复使用时,就会用到堆栈。

二、堆栈指令

1. PUSH指令

功能:

将操作数压入堆栈顶部。操作数可以是寄存器、内存单元或者立即数(在某些情况下)。当执行PUSH指令时,堆栈指针(RSP - Stack Pointer,在64 - bit模式下)会自动减8(因为64 - bit数据的大小为8字节),然后将操作数存放到新的堆栈顶部位置。

压入寄存器:push rax,将rax寄存器中的值压入堆栈。

压入内存数据:假设var1是一个已定义的双字(DWORD)变量,push [var1],将变量var1中的值压入堆栈。

2. POP指令

功能:

与PUSH指令相反,POP指令从堆栈顶部弹出一个数据到操作数指定的位置。操作数可以是寄存器或者内存单元。执行POP指令时,首先将堆栈顶部的数据取出,然后将堆栈指针RSP自动加8。

弹出到寄存器:pop rbx,将堆栈顶部的数据弹出到rbx寄存器中。

弹出到内存:假设var2是一个已定义的内存单元,pop [var2],将堆栈顶部的数据弹出到var2内存单元中。

3. PUSHFD / POPFD(64 - bit模式下对应的PUSHFQ / POPFQ)指令

功能:

PUSHFD(PUSH Flags Double - word)指令用于将32 - bit的标志寄存器(EFLAGS)的值压入堆栈;在64 - bit模式下,PUSHFQ(PUSH Flags Quad - word)将64 - bit的标志寄存器(RFLAGS)的值压入堆栈。

POPFD(POP Flags Double - word)指令用于从堆栈中弹出数据到32 - bit的标志寄存器(EFLAGS);在64 - bit模式下,POPFQ(POP Flags Quad - word)从堆栈中弹出数据到64 - bit的标志寄存器(RFLAGS)。

保存标志寄存器:pushfq,将当前的标志寄存器值压入堆栈。

恢复标志寄存器:popfq,从堆栈中弹出数据恢复标志寄存器的值。

4. PUSHA / POPA(64 - bit模式下对应的PUSHAD / POPAD)指令

功能:

PUSHA(PUSH All)和PUSHAD(PUSH All Double - words / Quad - words)指令用于将所有的通用寄存器(在16 - bit / 32 - bit或64 - bit模式下相应的通用寄存器)的值依次压入堆栈。

POPA(POP All)和POPAD(POP All Double - words / Quad - words)指令用于从堆栈中依次弹出数据到所有的通用寄存器,恢复寄存器的值。

保存所有通用寄存器:pushad,按照特定顺序将通用寄存器的值压入堆栈。

恢复所有通用寄存器:popad,按照相反顺序从堆栈中弹出数据到通用寄存器。

64位汇编语言基础