通常流水线的操作如下:
- 根据CS:IP取指令
- 译码
- 取源操作数(有些指令没有)
- 执行指令功能
- 写入结果(有些指令没有)
存储器寻址方式:
- 直接寻址 :mov ax,[1234]
2. 寄存器间接寻址:mov ax,[bx]
8086 支持的间接寻址寄存器是bx,bp,si,di
3. 寄存器相对寻址:mov ax, [bx+1234] ,bp默认SS段寄存器,其他默认DS段寄存器
4. 基址变址寻址:mov ax, [bx+si]
5. 相对基址变址寻址:mov ax, [bx+si+offset]
6. 比例因子寻址(80386)
6.1 相对比例因子寻址
6.2 基址变址比例因子寻址
6.3 相对基址变址比例因子寻址
探索汇编指令格式:
reg
06 00 000 110
0E 00 001 110
16 00 010 110
1E 00 011 110
26 00 100 110
2E 00 101 110
36 00 110 110
3E 00 111 110
随意写3句汇编
07 00 000 111 [bx]
04 00 000 100 [si]
05 00 000 101 [di]
观察发现只有最后3bit变化,从000~111共8种,排序如下:
00 00 000 000 [bx+si]
01 00 000 001 [bx+di]
02 00 000 010 [bp+si]
03 00 000 011 [bp+di]
04 00 000 100 [si]
05 00 000 101 [di]
06 00 000 110 [imm]
07 00 000 111 [bx]
变址是imm8的情况:
reg
40 01 000 000 [bx+si+imm8]
41 01 000 001 [bx+di+imm8]
42 01 000 010 [bp+si+imm8]
43 01 000 011 [bp+di+imm8]
44 01 000 100 [si+imm8]
45 01 000 101 [di+imm8]
46 01 000 110 [bp+imm8]
47 01 000 111 [bx+imm8]
变址是imm16的情况:
reg
80 10 000 000 [bx+si+imm16]
81 10 000 001 [bx+di+imm16]
82 10 000 010 [bp+si+imm16]
83 10 000 011 [bp+di+imm16]
84 10 000 100 [si+imm16]
85 10 000 101 [di+imm16]
86 10 000 110 [bp+imm16]
87 10 000 111 [bx+imm16]
C781 1100011 1 10 000 001
C781 1100011 1 10 000 001
C783 1100011 1 10 000 011
C787 1100011 1 10 000 111
C687 1100011 0 10 000 111
C647 1100011 0 01 000 111
1 WORD PTR
0 BYTE PTR
01 offset8
10 offset816
Mod 00 无基址寄存器
Mod 01 偏移量是BYTE
Mod 10 偏移量是DWORD
mov指令执行过程:
mov ax, 1234
1, CS:IP确定指令位置,取到指令队列
2, EU开始译码
3, CS:IP++得到34,存到BIU的内部暂存器
4, CS:IP++得到12,存到BIU的内部暂存器
5, 内部暂存器中的值1234传送到AX
Mov ax,[1234]
1, CS:IP确定指令位置,取到指令队列
2, EU开始译码
3, CS:IP++得到34,存到BIU的内部暂存器
4, CS:IP++得到12,存到BIU的内部暂存器
5, DS和内部暂存器中的值1234组合,取出内存[1234]中的值,传送内部暂存器
6,内部暂存器中的值传送到AX
Mov ax,[bx]
1, CS:IP确定指令位置,取到指令队列
2, EU开始译码
3, CS:IP++得到07,存到BIU的内部暂存器
4, DS和内部暂存器中的值组合,取出内存[bx]中的值,传送内部暂存器
5,内部暂存器中的值传送到AX
Mov ax,[bx+1234]
1, CS:IP确定指令位置,取到指令队列
2, EU开始译码
3, CS:IP++得到87,取到指令队列
4, EU开始译码,并将bx送入ALU
5,CS:IP++得到34,取到指令队列
6,CS:IP++得到12,取到指令队列
7,bx和1234在ALU中相加,结果送入 BIU的内部暂存器
8, DS和内部暂存器中的值组合,取出内存[bx+1234]中的值,传送内部暂存器
9,内部暂存器中的值传送到AX
Mov ax,[bx+si]
1, CS:IP确定指令位置,取到指令队列
2, EU开始译码
3, CS:IP++得到00,取到指令队列
4, EU开始译码,将bx,si送入ALU
5, bx+si的结果送入BIU的内部暂存器
6,DS和内部暂存器中的值组合,取出内存[bx+si]中的值,传送内部暂存器
7,内部暂存器中的值传送到AX
Mov ax,[bx+si+1234]
1, CS:IP确定指令位置,取到指令队列
2, EU开始译码
3, CS:IP++得到80,取到指令队列
4, EU开始译码,将bx,si送入ALU
5. CS:IP++得到34,BIU的内部暂存器
6, CS:IP++得到12,BIU的内部暂存器
7,BIU的内部暂存器将值1234送入ALU
8,bx+si+1234的结果送入BIU的内部暂存器
9,DS和内部暂存器中的值组合,取出内存[bx+si+1234]中的值,传送内部暂存器
10,内部暂存器中的值传送到AX
通用数据传送指令
MOV reg/mem, imm
Mov reg/mem/seg, reg
Mov reg/seg, mem
Mov reg/mem, seg
Mov word ptr[bx], 1234 ;传立即数时要说明word或byte
Mov [si], al ;al已经隐含说明数据长度
XCHG reg, reg/mem
XLAT(tanslate)
将bx指定的缓冲区中,al指定的位移处的一个字节取出,赋值给al,相当于al <--- [bx+al]
Push
Pop
LAHF (Load AH from Flag) 标志寄存器的低字节送入AH
SAHF(Store AH into Flag) AH送入标志寄存器的低字节
PUSHF(Push Flag) 16bit
POPF(Pop Flag) 16bit
PUSHFD 2bit
POPFD 32bit
LEA
Lea reg, mem
LDS reg,mem
Reg <---mem
DS <---mem+2
LES reg,mem
Reg <---mem
ES <---mem+2
IN AL,imm8 AL<--IO端口
IN AX,imm8
IN AL,DX
IN AX,DX
ADD
ADC 源操作数和目标操作数相加,再加上CF(1或0),结果送到目标操作数
ADC AX, BX ;AX = AX + BX + CF
例如计算12345678h+66668888h,结果用cx.dx.ax联合表示一个大数
SBB 类似ADC,只不过是减法
SBB AX, BX ;AX = AX - BX - CF
NEG 求补,用0减去操作数(或者说取反加一),结果返回给操作数,相当于C语言中的取负数。
例如0-1 = -1,补码表示为FFFF,相当于0001取反加一
如三目运算:A==0?0:-1;
Mov ax, A
Neg ax
Sbb ax,ax
Neg ax相当于0-ax,当ax=0时CF为0,否则CF为1
Sbb ax,ax相当于ax = ax-ax-CF,相当于ax = 0-CF,CF为0时结果为0,CF为1时结果为-1
综上,ax=0时CF为0,CF为0时结果为0;
ax!=0时CF为1,CF为1时结果为-1;