PUSH进栈指令和POP出栈指令
Posted ʚVVcatɞ
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了PUSH进栈指令和POP出栈指令相关的知识,希望对你有一定的参考价值。
PUSH进栈指令
- 指令格式:PUSH 源
- 指令功能:将源操作数推入堆栈。
- 源操作数可以是16位通用寄存器、段寄存器或存储器中的数据字,但不能是立即数。堆栈是以“先进后出”的方式工作的一个存储区,栈区的段地址由SS寄存器的内容确定。堆栈的最大容量可为64K,即一个段的最大容量。堆栈指针SP始终指向栈顶,其值可以从FFFEH(偶地址)开始,向低地址方向发展,最小为0。
- 每次执行PUSH操作时,先修改SP的值,使SP←SP-2后,然后把源操作数压入堆栈汇中SP指示的位置上,低位字节放在较低地址单元,高位字节放在较高地址单元。由于堆栈操作都是以字为单位进行的,所以SP总是指向偶地址单元。SS和SP的值可由指令设定。
POP出栈指令
- 指令格式:POP 目的
- 指令功能:把当前SP所指向的堆栈顶部的一个字送到指定的目的操作数中。
- 目的操作数可以是16位通用寄存器、段寄存器或存储单元,但CS不能作目的的操作数。每执行一次出栈操作,SP←SP+2,即SP向高地址方向移动,指向新的栈顶。
例: 设SS=2000H, SP=10H,AX=2233,BX=3344,CX=0000,依次执行下列指令:
注:栈的大小 = 16字节 = 8个字
PUSH AX
PUSH BX
POP CX
POP BX
以下是执行PUSH AX指令后产生的变化
SP = 0010H 转换为十进制为16
SP = 16 - 2 = 14 转换为十六进制为 E
以下是执行PUSH BX指令后产生的变化
SP = 000EH 转换为十进制为 14
SP = 14 - 2 = 12 转换为十六进制为 C
以下是执行POP CX指令后产生的变化
SP = 000CH 转换为十进制为 12
SP = 12 + 2 = 14 转换为十六进制为 E
以下是执行POP CX指令后产生的变化
SP = 000EH 转换为十进制为14
SP = 14 + 2 = 16 转换为十六进制为 10H
注意:
段地址:偏移地址
SS : SP 它们永远指向栈顶数据
例:
利用栈交换AX 和 BX中的数据
push ax
push bx
pop ax
pop bx
例:
假设AX = 001AH,BX = 001BH,然后删除成0,利用栈恢复AX和BX中的数据
mov bx,2000
mov ss,bx
mov sp,10H
mov ax,001AH
mov bx,001BH
push ax
push bx
mov ax,0
mov bx,0
pop bx
pop ax
例:
假设将 10000H -1000FH这段空间当做栈,初始状态栈是空的,此时 SS = 1000H,SP = ?
0 1 2 3 4 5 6 7 8 9 A B C D E F = 16字节
SS = 1000:0 + 10H = 1000 : 10H
SP = 10H
注:
- 在使用堆栈的时候,需要注意栈越界问题,在汇编语言中,栈越界是没有提示的,需要自己留意。
- 一个栈能够存放最多 32768个字型数据。
- SP的范围为0 — FFFFH 字节。
例:
1)使其可以将 10000H — 1000FH 中的8个字型数据,逆序复制到 20000H—2000FH
10000H 23H 20000H 33H
10001H 01H 20001H 11H
10002H 66H
10003H 22H
........
1000CH 44H 2000CH 66H
1000DH 78H 2000EH 22H
1000EH 33H 2000EH 23H
1000FH 11H 2000FH 01H
mov ax, 1000H
mov ds,ax
mov bx,2000H
mov ss,bx
mov sp,10H
;1000H * 10H + 0 10000H 中字型数据 0123H
push ds:[0] ; → SS:SP-2
push ds:[2]
push ds:[4]
push ds:[6]
push ds:[8]
push ds:[A]
push ds:[C]
push ds:[E]
2)使其可以将 10000H — 1000FH 中的8个字型数据,逆序复制到 20000H—2000FH
mov ax,2000H
mov ds,ax
mov bx,1000H
mov ss,bx
mov sp,0
pop ds:[E] ; → SS:SP → ds:[E] → 2000:E → SP + 2
pop ds:[C]
pop ds:[A]
pop ds:[8]
pop ds:[6]
pop ds:[4]
pop ds:[2]
pop ds:[0]
以上是关于PUSH进栈指令和POP出栈指令的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向x86 汇编 ( push / pop 入栈 / 出栈 指令 | ret / retn 函数调用返回指令 | set 设置目标值指令 )
Android 逆向x86 汇编 ( push / pop 入栈 / 出栈 指令 | ret / retn 函数调用返回指令 | set 设置目标值指令 )