寄存器--内存读写--堆栈

通用寄存器

32位 16位 8位 编号
EAX AX AL 0
ECX CX CL 1
EDX DX DL 2
EBX BX BL 3
ESP SP AH 4
EBP BP CH 5
ESI SI DH 6
EDI DI BH 7

MOV的语法:

作用:拷贝源操作数到目标操作数

  1. 源操作数可以是立即数、通用寄存器、段寄存器、或者内存单元
  2. 目标操作数可以是通用寄存器、段寄存器或者内存单元
  3. 操作数的宽度必须一样
  4. 源操作数和目标操作数不能同时为内存单元

r表示通用寄存器,m代表内存,imm代表立即数

MOV 目标操作数 源操作数
MOV r/m8 r8
MOV r/m16 r16
MOV r/m32 r32
MOV r8 r/m8
MOV r16 r/m16
MOV r32 r/m32
MOV r8 imm8
MOV r16 imm16
MOV r32 imm32

内存读写-寻址

寄存器与内存的区别:

  1. 寄存器位于CPU内部,执行速度快,但比较贵
  2. 内存速度相对较慢,但成本较低,所以可以做的很大
  3. 寄存器和内存没有本质区别,都是用于存储数据的容器,都是定宽的
  4. 寄存器常用的有八个
  5. 计算机中常用的计量单位
  6. 内存的数量特别庞大,无法每个内存单元都起一个名字,所以用编号来代替,每一个字节都会有一个编号

补充:

  1. 32位计算机指的是寻址宽度是32位
  2. BYTE 字节 = 8 (BIT)
  3. WORD 字 = 16(BIT)
  4. DWORD 双字 = 32(BIT)

内存格式

  • 每个内存单元的宽度为8
  • 编号 称为 地址

从指定内存中读取/写入数据

mov dword ptr ds:[0x0012FF34],0x12345678
mov eax ,dword ptr ds:[0x0012FF34]
dword : 要读/写多少 此时是4字节
ptr:Point 代表后面是一个指针
ds:段寄存器
【0x0012FF34】:内存编号,必须是32位

注意:地址编号不要随便写,因为内存是有保护的,并不是所有内存都可以直接读写(需要特别处理),建议地址编号写成exp的值

寻址公式一:【立即数】

读取内存的值:
MOV EAX , DWORD PTR DS:[0x13FFC4]
向内存中写入数据:
MOV DWORD PTR DS:[0x13FFC4]
获取内存编号:
LEA EAX,DWORD PTR DS:[0x13FFC4]

寻址公式二:【reg】 reg代表寄存器 可以是8个通用寄存器中的任意一个

读取内存的值:
MOV ECX,0x13FFC4
MOV EAX,DWORD PTR DS:【ECX】
向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX],0x88888888
获取内存编号:
LEA EAX,DWORD PTR DS:[EDX]
MOV EAX,DWORD PTR DS:[EDX]

寻址公式三:【reg+立即数】

读取内存的值:

MOV ECX,0x13FFD0
MOV EAX,DWORD PTR DS:[ECX+4]
向内存中写入数据:
MOV EDX,0x13FFD8
MOV DWORD PTR DS:[EDX+0xC],0x88888888
获取内存的编号:
LEA EAX,DWORD PTR DS:[EDX+4]
MOVG EAX,DWORD PTR DS:[EDX+4]

寻址公式四:【reg+reg*【1,2,4,8】】

读取内存的值:
MOV EAX,0x13FFD8
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4]
向内存中写入数据:
MOV EAX,0x13FFD8
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4],0x88888888
获取内存的编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4]

寻址公式五:【reg+reg*【1,2,4,8】+立即数】

读取内存的值:
MOV EAX,13FFD8
MOV ECX,2
MOV EDX,DWORD PTR DS:[EAX+ECX*4+4]
向内存中写入数据:
MOV EAX,13FFD8
MOV ECX,2
MOV DWORD PTR DS:[EAX+ECX*4+4],88888888
获取发内存的编号:
LEA EAX,DWORD PTR DS:[EAX+ECX*4+2]

堆栈的实现

压入数据

MOV EBX, 13FFDC BASE
MOV EDX, 13FFDC TOP
方式一
MOV DWORD PTR DS:[EDX-4],0xAAAAAAAA
SUB EDX, 4

方式二
SUB EDX, 4
MOV DWORD PTR DS:[EDX],0xBBBBBBBB

方式三
MOV DWORD PTR DS:[EDX-4],0xDDDDDDDD
LEA EDX,DWORD PTR DS:[EDX-4]

方式四
LEA EDX, DWORD PTR DS:[EDX-4]
MOV DWORD PTR DS:[EDX],0xEEEEEEEE

读取第N个数

方式一:通过Base加偏移来读取
读第一个压入的数据:
MOV ESI,DWORD PTR DS :[EBX-4]
读第四个压入的数据:
MOV ESI,DWORD PTR DS:[EBX-0x10]

方式二:通过Top加偏移来读取
读第二个压入的数据:
MOV ESI,DWORD PTR DS:[EBX+4]
读第三个压入的数据:
MOV EDI ,DWORD PTR DS:[EBX+8]

弹出数据

方式一:
MOV ECX,DWORD PTR DS:[EDX]
LEA EDX,DWORD PTR DS:[EDX+4]

方式二:
MOV ESI ,DWORD PTR DS:[EDX]
ADD EDX,4

方式三:
LEA EDX,DWORD PTR DS:[EDX+4]
MOV EDI,DWORD PTR DS:[EDX-4]

EFLAGS(eflags)寄存器

1、进位标志CF(Carry Flag)

如果运算结果的最高位产生了一个进位或借位,那么其值为1,否则,其值为0
MOV AL ,0xEF MOV AL,0xFE
ADD AL,2 ADD AL,2

2、奇偶标志PF(Parity Flag)

奇偶标志PF用于反映运算结果中“1的个数”的奇偶性
如果1的个数为偶数,则PF的值为1,否则其值为0
MOV AL , 3
ADD AL, 3
ADD AL , 2

3、辅助进位标志AF(Auxiliary Carry Flag)

在发生下列情况时,辅助进位标志AF的值被置为1,否则其值为0:
(1)、在字操作时,发生低字节向高字节进位或借位时:
(2)、在字节操作时,发生低四位向高四位进位或借位时
MOV EAX,0x55EEFFFF MOV AX,5EFE MOV AL,4E
ADD EAX,2 ADD AX,2 ADD AL,2

4、零标志ZF(Zero Flag)

零标志ZF用来反映运算结果是否为0
如果运算结果为0,则其值为1,否则其值为0
XOR EAX,EAX
MOV EAX,2
SUB EAX,2

5、符号标志SF(Sign Flag)

符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同
MOV AL, 7F
ADD AL, 2

6、溢出标志OF(Overflow Flag)

溢出标志OF用于反映有符号数加减运算所得到结果是否溢出
如果运算结果超过当前运算位数所能表示的范围,则成为溢出,OF的值被置为1,否则,OF的值被清为0

最高位进位与溢出的区别:

  • 进位标志表示无符号数运算结果是否超出范围
  • 溢出标志表示有符号数运算结果是否超出范围
    溢出主要是给有符号运算使用过的,在有符号的运算中,有如下的规律:
  • 正 + 正 = 正 如果结果是负数,则说明有溢出
  • 负 + 负 = 负 如果结果是正数,则说明有溢出
  • 正 + 负 永远都不会有溢出
1、无符号、有符号都不溢出
MOV AL , 8
ADD AL, 8
2、无符号溢出、有符号不溢出
MOV AL, OFF
ADD AL, 2
3、无符号不溢出、有符号溢出
MOV AL, 7F
ADD AL, 2
4、无符号、有符号都溢出
MOV AL, OFE
ADD AL, 80

猜你喜欢

转载自www.cnblogs.com/snailzh/p/13198689.html