基础
- 程序设计时分段管理,但有两个限制:
- 每个段最大为64KB
- 段只能开始于低4位地址全为0的物理地址处
- 逻辑地址=段基地址∶偏移地址
- 16位段寄存器保存20位段起始地址的高16位
- 偏移地址也用16位数据表示
- 物理地址=段地址×16+偏移地址
- 通用寄存器
- 数据寄存器:AX(累加器),BX(基址),CX(计数器),DX(数据)
- 变址寄存器:SI(源地址),DI(目的地址),BP(基址指针),SP(堆栈)
- 段寄存器:CS(代码),SS(堆栈),DS(数据),ES(附加)
- 标记寄存器:FLAGS
- 指令指针:IP
基本段的逻辑地址
- 代码段(Code Segment)
- 段基地址:代码段寄存器CS指示
- 偏移地址:指令指针寄存器IP保存
- 数据段(Data Segment)
- 段基地址:数据段寄存器DS指示(有时也用附加段寄存器ES指示)
- 偏移地址:各种存储器寻址方式计算出来
- 堆栈段(Stack Segment)
- 段基地址:堆栈段寄存器SS指示
- 偏移地址:堆栈指针寄存器SP保存
数据的表示和寻址
- 非压缩BCD码:一个字节表达一位BCD码(低4位表达数值,高4位常设置为0)
- 以字母A~F开头的十六进制常数,要加前导0
- 变量定义伪指令DB、DW、DD(4b)、DF(6b)、DQ(8b)、DT(10b)
- 字节量BYTE 字量WORD 双字量DWORD 3字量FWORD 4字量QWORD 10字节量TBYTE
- “?”表示初值不确定,即未赋初值
- 重复操作符 DUP(重复参数)
- 小端方式:低字节数据存放在低地址存储单元
- ORG 参数 ;控制存放的偏移地址
- ALIGN N ;控制对齐N字节边界(模N地址,整除)
- 地址操作符
- [ ] 括起的表达式作为存储器地址指针
- $ 返回当前偏移地址
- OFFSET 变量名 返回变量名所在段的偏移地址
- SEG 变量名 返回段基地址(高16位)
- 类型操作符
- 类型名 PTR 变量名 将变量名按照指定的类型使用
- TYPE 变量名 返回占用字节空间的字量数值
- LENGTHOF 变量名 返回整个变量的数据项数
- SIZEOF 变量名 返回整个变量占用的字节数
数据寻址方式
- 立即数寻址:数据在指令代码中,用常量表达
- 寄存器寻址:数据在寄存器中,用寄存器名表示
- 存储器寻址:数据在主存中,用存储器地址代表
- 默认规定:数据在DS指向的数据段;BP或SP作为基地址,数据在SS指向的堆栈段
- 使用段超越指令前缀,段寄存器名后跟英文冒号 如CS:
- 16位有效地址=基址寄存器(BX和BP)+变址寄存器(SI和DI)+位移量
- 直接寻址:MOV AX,COUNT([COUNT] | DS:[2000H]); 假设count的有效地址为2000H,三条指令等价
- 寄存器间接寻址:寄存器内容=偏移地址=有效地址
- 8086只能使用BX、SI和DI寄存器作为间接寻址
- 寄存器间接寻址没有说明存储单元类型
- mov al,[bx] 等价于mov al,ds:[2000h] (假设bx=2000h)
- 寄存器相对寻址:有效地址是寄存器内容与位移量之和
- 8086只能使用BX、BP、SI和DI寄存器
- 使用BP默认访问堆栈段
- 基址变址寻址: 使用基址寄存器内容加上变址寄存器内容形成有效地址寻址操作数
- 8086的基址寄存器是BX和BP
- 8086的变址寄存器是SI和DI
- 使用BP默认访问堆栈段
- 相对基址变址寻址:由基址寄存器内容、变址寄存器内容及位移量求和构成存储器操作数的有效地址
通用数据处理指令
数据传送类指令
除标志寄存器传送指令外,均不影响标志位
- MOV reg/mem,imm | MOV reg/mem/seg,reg | MOV reg/seg,mem | MOV reg/mem,seg
- 双操作数必须类型一致
- 操作数必须有明确的类型
- 双操作数不允许都是主存单元
- 不可随意操作专用寄存器 (如立即数不能直接传送段寄存器)
- XCHG reg,reg/mem | XCHG reg/mem,reg
- 空操作指令NOP(= XCHG AX,AX)实现短时间延时 临时占用代码空间
- 堆栈操作指令:
- SS指向堆栈段的起始位置,SP指定栈顶
- 数据进入堆栈,SP逐渐减小 数据依次弹出、SP逐渐增大
- PUSH r16/m16/seg 小端对齐
- POP r16/m16/seg
- LEA r16,mem ;地址传送指令获取存储器操作数的地址
- LEA指令执行时计算出偏移地址
- OFFSET操作符在汇编阶段取得变量的偏移地址
- XLAT指令功能:AL←[BX+AL]
- 标志传送指令
- CLC 复位进位标志:CF←0
- STC 置位进位标志:CF←1
- CMC 求反进位标志:原为0变为1,原为1变为0
- CLD 复位方向标志:DF←0,串操作后地址增大
- STD 置位方向标志:DF←1,串操作后地址减小
- CLI 复位中断标志:IF←0,禁止可屏蔽中断
- STI 置位中断标志:IF←1,允许可屏蔽中断
算术运算类指令
进位标志CF,溢出标志OF,零标志ZF,符号标志SF,奇偶标志PF(最低字节)
加法指令
- 加法指令 ADD reg,imm/reg/mem | ADD mem,imm/reg
- 带进位加法指令 ADC
- 增量指令 INC
除INC不影响进位标志CF外
其他指令按定义影响全部状态标志位
减法指令
- 减法指令 SUB reg,imm/reg/mem | SUB mem,imm/reg
- 带借位减法指令 SBB
- 减量指令 DEC
- 求补指令 NEG reg/mem ;reg/mem←0-reg/mem
- 比较指令 CMP
- 将目的操作数减去源操作数,差值不回送目的操作数,按照减法结果影响状态标志
除DEC不影响CF标志外
其他按定义影响全部状态标志位
- 将目的操作数减去源操作数,差值不回送目的操作数,按照减法结果影响状态标志
乘法和除法指令
- 有符号数指令前用I(sIgned)表示
- 隐含使用AX 低位(和DX)寄存器
- MUL src (8位乘法:AX=AL×r8/m8 16位乘法:DX.AX=AX×r16/m16)
- DIV src
- 8位除法:AL←AX÷r8/m8的商 AH←AX÷r8/m8的余数
- 16位除法:AX←DX.AX÷r16/m16的商 DX←DX.AX÷r16/m16的余数)
其他
- 零位扩展(前面加0实现位数扩展)和符号扩展(前面加符号位(最高位)实现位数扩展)
- cbw ;AL符号扩展到AX
- cwd ;AX符号扩展到DX和AX寄存器对
位操作类指令
逻辑运算指令
- 逻辑与指令 AND
- 逻辑或指令 OR reg,imm/reg/mem | OR mem,imm/reg
- 逻辑非指令 NOT reg/mem
- 逻辑异或指令 XOR
- 测试指令 TEST:按位进行逻辑与运算,不返回逻辑与结果
除NOT指令不影响标志外
其他逻辑指令: 使OF=CF=0, 并根据结果按定义影响ZF、SF和PF
移位指令
- 逻辑左移指令 SHL reg/mem,1/CL ;逻辑左移:最低位补0,最高位进入CF
- 逻辑右移指令 SHR reg/mem,1/CL ;逻辑右移:最高位补0,最低位进入CF
- 算术左移指令 SAL;算术左移,与SHL是同一条指令
- 算术左移指令 SAR ;算术右移:最高位不变,最低位进入CF
- 不带进位循环左移指令 ROL
- 不带进位循环右移指令 ROR
- 带进位循环左移指令 RCL
- 带进位循环右移指令 RCR
程序结构
- JMP label;无条件转移,段内相对寻址,段间直接寻址
- JMP r16 ;程序转向寄存器指定的地址 寄存器间接寻址
- Jcc label;条件满足,发生转移;否则,顺序执行下条指令(cc表示利用标志判断的条件)
- JZ(JE)和JNZ(JNE):利用零位标志ZF
- JS和JNS:利用符号标志SF
- JO和JNO:利用溢出标志OF
- JP(JPE)和JNP(JPO):利用奇偶标志PF
- JC和JNC:利用进位标志CF
- 无符号数用高(Above)、低(Below):JB(JNAE),JBE(JNA),JNB(JAE)
- 有符号数用大(Greater)、小(Less)
- je; 两数相等,转移
- LOOP label;CX←CX-1;若CX≠0,循环到LABEL,否则,顺序执行
- JCXZ label;CX=0,转移;否则顺序执行
- MOVSB|MOVSW ;串传送:ES:[DI]←DS:[SI] ;然后:SI←SI±1/2,DI←DI±1/2
- REP ;执行一次串指令,CX减1;直到CX=0