寄存器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
AH&AL=AX(accumulator):累加寄存器 
BH&BL=BX(base):基址寄存器
CH&CL=CX(count):计数寄存器
DH&DL=DX(data):数据寄存器
SP(Stack Pointer):堆栈指针寄存器
BP(Base Pointer):基址指针寄存器
SI(Source Index):源变址寄存器
DI(Destination Index):目的变址寄存器
IP(Instruction Pointer):指令指针寄存器
CS(Code Segment)代码段寄存器
DS(Data Segment):数据段寄存器
SS(Stack Segment):堆栈段寄存器
ES(Extra Segment):附加段寄存器
OF overflow flag 溢出标志 操作数超出机器能表示的范围表示溢出,溢出时为1.
SF sign Flag 符号标志 记录运算结果的符号,结果负时为1.
ZF zero flag 零标志 运算结果等于0时为1,否则为0.
CF carry flag 进位标志 最高有效位产生进位时为1,否则为0.
AF auxiliary carry flag 辅助进位标志 运算时,第3位向第4位产生进位时为1,否则为0.
PF parity flag 奇偶标志 运算结果操作数位为1的个数为偶数个时为1,否则为0.
DF direcion flag 方向标志 用于串处理.DF=1时,每次操作后使SI和DI减小.DF=0时则增大.
IF interrupt flag 中断标志 IF=1时,允许CPU响应可屏蔽中断,否则关闭中断.
TF trap flag 陷阱标志 用于调试单步操作.

寄存器

EFLAGS寄存器(标志寄存器)

8086/8088 CPU中有一个16位的标志寄存器,包含了9个标志寄存器,分别为6个运算结果标志寄存器和3个状态控制标志寄存器

运算结果标志

第0位 CF(Carry Flag) 进位标志

进行无符号运算时运算结果的最高位产生了一个进位或者借位,其值为1,否则为0。
如8位的运算
80+40
换算成2进制
1000 0000
+0100 0000
—————
1100 0000
首位并没有进位 CF位为0

80-81
1000 0000
-1000 0001
—————
1111 1111
首位向前借了一位 CF位变为1

PF(Parity Flag) 奇偶标志

反应运算结果中最低有效字节“1”的个数奇偶性 偶1奇0

803 换算成2进制
0011 0010 0011
加1变为
0011 0010 0100
此时结果存在4个1,“1”为偶数,但是PF位并不会变为1
因为PF位只会看最低有效字节,也就是
0011 0010 0100
最后面的1字节 此时最低有效字节只有一个1,所以PF位为0
当再加1时 变为
0011 0010 0101
此时最低有效字节存在两个“1”
PF的值变为1

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

有两种情况值为1
1.在字操作时,发生低字节向高字节进位或借位时
2.在字节操作时,发生低4位向高4位进位或借位时

ZF(Zero Flag) 零标志

运算结果为0时其值为1

SF(Sing Flag) 符号标志

符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同

OF(Overflow Flag) 溢出标志

第一位为标志1为负数,0为正数

进行有符号运算时如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0

加法:若同符号数相加,而结果符号与之相反,则OF=1,否则OF=0
加法:若不同符号相加,一定没有溢出
减法:被减数与减数异号,而结果的符号与减数相同则OF=1,否则OF=0

比如 80-40

1
2
mov al,80
sub al,40

相当于

1
2
mov al,80
add al,0C0

1000 0000
+1100 0000
—————

符号位有进位:1
最高位有效数值位线符号位产生进位:0

1 xor 0 == 1 所以 OF=1

状态控制标志

汇编小记

堆栈操作

堆栈操作

OD一些命令的写法

OD

逻辑运算

逻辑运算

寻址公式

读取内存中的值 mov eax,dword ptr ds:[0x13FFC4]
向内存中写入数值 mov dword ptr ds:[0x13FFC4],eax
获取内存编号 lea eax,dword ptr ds:[0x13FFC4]

一些其他操作指令

ADC:带进位加法 将运算结果加上CFlag寄存器的值
SBB:带错位减法 将运算结果减去CFlag寄存器的值
XCHG:交换数据
MOVS:移动数据
STOS:将Al/AX/EAX的值存储到[EDI]指定的内存单元
REP:按计数寄存器 (ECX) 中指定的次数重复执行字符串指令
MOVSX:操作不相等位数的寄存器时 使用符号位填充 (正数0 负数F)
MOVZX:操作不相等位数的寄存器时 使用0填充
INC:每执行一次将寄存器的值递增1 (相当于 寄存器=寄存器+1)
DEC:每执行一次将寄存器的值递减1 (相当于 寄存器=寄存器-1)
MUL:无符号乘法 默认与EAX相乘 运算结果放在EAX和EDX里 (如果EAX宽度不够 那么将多出来的部分储存到EDX里)
DIV:无符号除法 默认与EAX相除 8位 将商存入AH将余数存入AL 16位 将商放在AX里余数放DX里 32位 将商放在EAX里余数放EDX里
IMUL:带符号乘法 单操作数 默认与EAX相乘 运算结果放在EAX和EDX里 (如果EAX宽度不够 那么将多出来的部分储存到EDX里)
双操作数 目标操作数(第一个操作数)乘以源操作数(第二个操作数) 源操作数可以是立即数、通用寄存器、内存位置 乘积放在目标操作数的位置 (如果EAX宽度不够 那么将多出来的部分储存到EDX里)
三操作数 这种形式需要一个目标操作数(第一个操作数)与两个源操作数(第二个与第三个操作数) 第一个源操作数可以为通用寄存器活内存位置 乘以第二个源操作数(立即数) 乘积储存到目标操作数(通用寄存器)
IDIV:带符号除法 和无符号除法一样 但是操作数必须是带符号的数 商和余数也都是带符号的数 且余数符号与被除数相同
XADD:表示交换并相加,即先将两个数交换,再将二者之和送给第一个数。

操作EIP

JMP:将需要跳转的地址写入EIP中 让CPU下一步执行
CALL:将需要跳转的地址写入EIP中 并将call的下一行当做返回地址压入堆栈
计算call下一行地址的方法: 当前EIP+指令长度

跳转

https://zhidao.baidu.com/question/108433452.html

je、jz

当z位为1时跳转(两个操作数相同、两个操作数相减等与0)

jne、jnz

当z位为0时跳转(两个操作数不相同、两个操作数相减不为0)

js

eax 0

ecx 1

cmp eax,ecx

运算结果为负数时跳转,SF标志位为1

jns

运算结果不为负数,SF标志位为0时跳转

jp、jpe

eax 0x14

ecx 0x11

cmp eax,ecx

奇偶标志位PF为1(偶数)时跳转

jnp、jpo

当p位为0时跳转(运算结果为奇数时)

jo

eax 7FFFFFFF

ecx 1

add eax,ecx

此运算结果溢出,OF标志位置1,jo跳转触发

jno

OF标志位为0,jno跳转触发

jB

cmp eax,ecx

无符号判断 当eax比ecx小发生借位或进位,CF标志位置1,jb跳转触发。

jnB

cmp eax,ecx

当eax比ecx大不发生借位或进位,CF标志位置0,jnb跳转触发。

jbe

第一个操作数大于或等于第二个操作数的时候,也就是当CF或ZF标志位为1时都会触发jbe跳转

jnbe、ja

第一个操作数大于第二个操作数的时候,也就是当CF或ZF标志位都为0时都会触发jnbe跳转

jl

cmp eax,ecx

有符号判断 当eax比ecx小,SF标志位置1,jb跳转触发。

循环