# 一、内存中的数据

# 1、存储方式

数据存储在内存中是以字节的单位反向存储的,如:4B5C6D3A, 在内存中存储顺序是 3A 6D 5C 4B (两个十六进制数为一个字节)。

# 2、可识别寻址方式

1、立即数
mov eax,dword ptr ds:[0xAAAA] (读取)
mov dword ptr ds:[0xAAAA],eax (写入)
lea eax,dword ptr ds:[0xAAAA] (读取地址)
lea:得到地址的指令

2、[reg]
mov ea,dword ptr ds:[ecx] (读取)
mov dword ptr ds:[ecx],eax (写入)
lea eax,dword ptr ds:[ecx] (读取地址)
注:eax 中存着一个代表地址的数

3、[reg + 立即数]
4、[reg+reg*{1\2\4\8}]
5、[reg+reg*{1\2\4\8}+ 立即数]

# 二、堆栈

# 1、基本原理

建立堆栈如图

堆栈是用两个寄存器标记出一段内存用于存储数据(一个标记栈底一个标记栈顶),使用堆栈的目的是:1 数据大寄存器存不下 2 需要寻址方便

寻址方式:从堆栈顶寄存器或者底寄存器 +- 个数得出所需地址数。(这种 +- 就是平时所说的偏移)

弹出数据(删除):只需将顶(底)偏移想要删除的内存个数即可。

# 2、堆栈指令

注:系统默认 EBP 为栈底,ESP 为栈顶。

# push

栈顶向上移并赋值,[x] 赋值给新开的内存空间。
格式:push [x]([x] 为立即数 \ 寄存器 \ 内存地址)

# pop

弹出栈内的值并自动下移,弹出的值赋值给 [y]。
格式;pop [y]([y] 为寄存器 \ 内存地址)

注:以上两个指令中不允许使用 8 位寄存器 \ 内存地址,如果使用的是 16 位的内存或寄存器那么栈顶只会偏移两个字节。

# pushad 与 popad

这两个指令成为堆栈平衡指令
pushad 是保存当前堆栈(包括所有寄存器中的值也保存),pop 是回复 pushad 保存的堆栈。
作用:在调试过程出错后起 “回档” 作用。

# 三、标志寄存器

# 1、寄存器位置

在这里插入图片描述

# 2、标志的意义

注:mov 指令不改变寄存器。

CF:判断最高位是否溢出(借位 \ 进位),无变化为零。(根据无符号数)
PF:判断运算结果中 “1” 个数的奇偶性,奇 0 偶 1。(只看最后两个字节)
AF:判断辅助位是否进位,无变化为 0。(辅助位 FFFFFFFF,FFFF,FF
ZF:判断结果是否为 0,运算结果为零则为 1。
SF:判断符号位(最高位),与结果最高位相同。
OF:判断是否溢出,溢出则为 1。(根据有符号数)
DF:方向标志位,决定方向。0 为加,1 为减。

CF 与 OF 主要取决于观测者,需要哪个看哪个。

# 四、指令

# ADC

带进位的加法,计算结果时会加上 CF 的值。
格式:acd r\m,r\m\i

# SBB

带借位的减法,计算时会再减去 CF 的值。
格式:sbb r\m,r\m\i

# XCHG

交换数据,只能容器到容器。
格式:xchg r\m,r\m

# MOVS

移动数据,内存到内存.
格式:
movs byte ptr es:[edi],byte ptr es:[esi] 简称 movsb
movs word ptr es:[edi],word ptr es:[esi] 简称 movsw
movs dword ptr es:[edi],dword ptr es:[esi] 简称 movsd
把 [esi] 中的移到 [edi] 中,并根据移动字节数改变 esi 和 edi 的值。

# STOS

将 al\ax\eax 的值存储到 [edi] 指定的内存单元。
格式:
stos byte ptr es:[edi] 简写 stosb
stos word ptr es:[edi] 简写 stosw
stos dword ptr es:[edi] 简写 stosd
至于是 al\ax\eax 中的哪一个则根据宽度来判断。

# REP

根据 ecx 的值决定重复执行后面代码的次数。
格式:rep movsw 等。

# JMP

给 eip 赋值,且不影响其他值(堆栈,寄存器等)
格式:jmp r\i

# CALL&RETN

同样是给 eip 赋值,不同的是他会将下一行指令的地址记录下来压入堆栈中,跳转后执行到 retn 时会回到记录的代码地址。
格式:call r\i

# CMP

原理和 sub 相同,不同于它不是真正的减去(不会影响存的数据),只会改变标志寄存器。常用来比较是否相等。(cmp eax,ecx)
格式:cmp r\m,r\m\i

# TEST

原理和 and 相同,机制和 cmp 相同,不改变实际值。常用来判断寄存器的值是否是零。(test eax,eax)
格式:test r\m,r\m\i

# 五、JCC

注:与 jmp 实质相同

1、JE\JZ 结果为零跳转(ZF=1)
2、JNE\JNZ 结果不为零跳转(ZF=0)

3、JS 结果为负跳转(SF=1)
4、JNS 结果为非负跳转(SF=0)

5、JP\JPE 结果中 1 为偶数个跳转(PF=1)
6、JNP\JPO 结果中 1 为奇数个跳转(PF=0)

7、JO 结果溢出跳转(OF=1)
8、JNO 结果不溢出跳转(OF=0)

无符号数:
9、JB\JNAE 结果溢出跳转(CF=1)
10、JNB\JAE 结果不溢出跳转(CF=0)

11、JBE\JN 小于等于跳转(ZF=1 or ZF=1)
12、JNBE\JA 大于跳转(ZF=0 and ZF=0)

有符号数:
13、JL\JNGE 小于跳转(SF!=OF)
14、JNL\JGE 大于等于跳转(SF=OF)

15、JLE\JNG 小于等于跳转(ZF=1 or SF!=OF)
16、JNLE\JG 大于跳转(ZF=0 and SF=OF)