标志寄存器FLAG
① 运算结果标志
(1) 进位标志CF 主要用于反应加法运算后是否产生进位或减法运算后是否产生借位(字节运算中第7位,字运算中第15位)
(2) 零标志ZF 用于反应运算结果是否为0
(3) 符号标志SF 用于反应运算结果首位是否为1
(4) 溢出标志OF 用于反应运算结果是否溢出
(5) 奇偶标志PF 用于反应运算结果1的个数是否为偶数个
(6) 辅助进位标志AF 用于表示是否发生低半字节是否向高半字节产生进位或借位.(第3,4位是否进位或借位.BCD加减法)
② 状态控制标志
(1) 方向标志 DF 当DF=1时,串操作指令按递减方式,当D=0时按递增方式(STD, CLD)
(2) 中断允许标志IF 决定CPU是否相应外部可屏蔽中断请求(STI, CLI)
(3) 追踪标志TF 决定CPU是否进入单步方式,只要用于程序调试
物理地址
从0地址开始,每16字节为一小段.
逻辑段的开始地址必须是16的倍数,逻辑段的最大长度为64K
1MB的存储器里,每一个存储单元都有一个唯一的20位地址称为该存储单元的物理地址.存储单元的逻辑地址有断值和偏移两部分组成.用如下形式表示: 段值 : 偏移
物理地址 = 段值×16 + 偏移
段寄存器
取指令: CS : IP
堆栈操作: SS : SP
当偏移涉及BP寄存器时,缺省引用SS.
当存取一个普通寄存器操作数时,自动选取DS或ES,再加上16位偏移(指针寄存器或直接地址偏移)
如果16进制数的最高位为字母,则应在其前加一个0
8086/8088寻址方式
寻址方式: 表示指令中用于说明操作数所在的地址的方法
1. 立即寻址方式
操作数包含在指令中.称为立即数
例: mov ax, 1234H(源操作数采取立即寻址方式)
ERROR: mov al, 1234H(16位不可以赋值给8位)
1. 寄存器寻址方式(较高的运算速度)
操作数在寄存器中
16位操作数,寄存器可以是通用寄存器
8位操作数,寄存器是8个8位寄存器.
例: mov ax, bx
mov si, ax
mov al, dh
2. 直接寻址方式
操作数在存储器中,指令包含操作数的有效地址,操作数一般在数据段中.所以操作数的地址就是DS加上指令中的16位偏移
例: mov ax, [8054H]
符号地址可以代替数值地址
Mov ax, value 等价于 mov ax, [value]
如果value在附加段,则应制定段超越前缀
Mov ax, ES: value huozhe mov ax, es: [value]
这种寻址方式常用于处理单个寄存器变量的情况,他可实现在64K字节的段内寻找操作数.直接寻址的操作数通常是程序使用的变量.
3. 寄存器间接寻址方式
操作数在存储器中,操作数有效地址在SI, DI, BX, BP四个寄存器之一.不适用段超越前缀明确制定段寄存器,那么如果有效地址在SI, DI, BX中,则以DS段寄存器为段值,如果有效地址在BP中,则以SS段寄存器为段值.
例: mov ax, [si]
Mov dl, CS: [bx]
4. 寄存器相对寻址方式
操作数在存储器中,操作数的有效地址是一个基址寄存器(BX, BP)或变址寄存器(SI,DI)的内容加上指令中给定的8位或16位偏移量之和.(8位数符号扩展成16位)
例: mov ax, [di + 1223H]
Mov ax, [si + 3H] 等价于 mov ax, 3[si]
5. 基址加变址寻址方式
操作数在存储器中,操作数的有效地址由基址寄存器(BX, BP)之一与变址寄存器(SI, DI)之一的内容相加.如果是BX,则以DS之内容为段值,如果是BS,则以SS之内容为段值.
例: mov ax, [bx][di] 等价于 mov ax, [bx+di]
如果(ds)=2100H, (bx)=0158H, (di)=10A5H 则EA=0158+10A5=11FD 那么物理地址为21000+11FD=221FDH
MOV DS:[BP+SI], AL
MOV AX, ES:[BX+SI]
这种寻址方式适用于数组或表格处理,用基址寄存器存放数组首地址,而用变址寄存器来定位数组中的个元素,或反之.
6. 相对基址加变址寻址方式
操作数在存储器中,操作数的有效地址由基址寄存器之一的内容与变址寄存器之一的内容及指令中给定的8位或16位位移量相加得到
在指令中给定的8位或16位位移量采用补码形式表示,8位被带符号扩张成16位
当所得的有效地址(OFFSET)超过0FFFFH是,就取其64K的模(余数).
MOV AX, [BX+DI+1234H] == MOV AX, 1234H[BX][DI]
MOV AX, 1234H[BX+DI] == MOV AX, 1234H[DI][BX]
六个功能组:
(1) 数据传送
(2) 算术运算
(3) 逻辑运算
(4) 串操作
(5) 程序控制
(6) 处理器控制
指令一般格式:
[ 标号: ] 指令助记符 [ 操作数1 [, 操作数2] ] [; 注释]
一、 数据传送指令
1. 传送指令
MOV DST, SRC
SRC可以使累加器, 寄存器, 存储单元以及立即数
DST可以使累加器, 寄存器和存储单元.
两个操作数必须要有一个寄存器.(除立即寻址, 立即数可以给存储单元) 立即数永远不能作为目的操作数
(1) 寄存器之间的数据传送
MOV AH, AL
DST和SRC不能同时使段寄存器,CS不能作为DST, IP不能作为DST和SRC
(2) 立即数送至通用寄存器或存储单元(各种存储器寻址方式)
MOV AL, 2 MOV VARB, -1 MOV [SI], 6543H
立即数不能直接传送至段寄存器.立即数永远不能作为目的操作数
(3) 存储器与寄存器间的数据传送
1. 交换指令
XCHG OPRD1, OPRD2
OPRD1和OPRD2可以是通用寄存器和存储单元.但不包括段寄存器,也不能同时是存储单元,还不能有立即数.可采用各种存储器寻址方式.
2. 地址传送指令
(1) LEA(Load Effective Address)
LEA REG, OPRD
该指令把操作数OPRD的有效地址(偏移地址)传送到操作数REG
OPRD必须是一个存储器操作数. REG必须是一个16位的通用寄存器
例:LEA AX, BUFFER ;BUFFER是变量名
LEA DS, [BS+SI]
LEA SI, [BP+DI+0F62H]
(2) LDS(Load pointer into DS)
LDS REG, OPRD
把OPRD中所含的32位地址指针的段值送到DS,偏移地址送到通用寄存器REG.
OPRD必须是一个32位的寄存器操作数.REG可以是16位的通用寄存器,但实际使用的往往是变址寄存器或指针寄存器.
例: LDS SL, POINTER; POINTER是一个双字变量
LDS SI, [10H] 如果(DS)=COOOH, (COO10H)=0180, (C0012H)=2000
则指令执行后: (SI)=0180H, (DS)=2000H.
(3) LES(Load pointer into ES)(同LDS)
LES REG, OPRD
例: LES DI, [BX] 如果执行前 (DS)=B000H, (BX)=080AH, (0B080AH)=05AEH, (0B080CH)=4000H
执行后 (DI)=05AEH, (ES)=4000H.
一、 堆栈操作指令
堆栈的存取必须以字为单位,SP指向字的低地址
1. 进栈指令PUSH
PUSH SRC(SP = SP - 2)
它先把SP减2,然后把SRC送入由SP所指的栈顶,SRC可以是REG, SEG, MEM16.
2. 出栈指令POP
POP DST(SP = SP + 2)
它先把SP所指的字数据送至DST,然后SP减2。
DST可以是reg,seg(除CS),mem16
二、 标志操作指令
1. 标志传送指令
(1) LAHF(Load AH with Flags)
采用固定寻址方式, 把SF, ZF, AF, PF, CF 传送到AH的指定位.标记位不受影响
(2) SAHF(Store AH intoFlags)
与LAHF相反, 这些标记位都要受到影响
(3) PUSHF
先把SP减2,然后把标志寄存器压栈
(4) POPF
把栈顶的一个字传送到标志寄存器.,然后把SP加2
2. 标志位操作指令
(1) 清进位标志指令CLC(CLear Carry flag)
CF = 0
(2) 置进位标志指令STC(SeT Carry flag)
CF = 1
(3) 进位标志取反指令CMC(CoMplement Carry flag)
CF = ~CF
(4) 清方向标志CLD(Clear Direction flag)
DF = 0 串操作指令时,使地址递增方式变化.
(5) 置方向标志STD(SeT Direction flag)
(6) 清中断允许标志CLI(Clear Interrupt enable flag)
IF = 0 CPU不响应来自外部装置的可屏蔽中断,但对不可屏蔽中断和内部中断都没有影响
(7) 置中断允许标志STI(SeT Interrupt enable flag)
三、 加减运算指令
1. 加法指令
ADD OPRD1, OPRD2 (OPRD1 += OPRD2)
掌握影响的符号位CF, ZF, OF, SF, AF, PF
若两个操作数符号相同而结果符号相反时则OF=1,否则都为0
2. 带进位加指令
ADC(ADd with Carry)
ADC OPRD1, OPRD2 (OPRD1 += OPRD2 + CF)
例子:执行两个双精度的加法(32位)
(DX)=0002H, (AX)=0F365H
(BX)=0005H, (CX)=0E024H
ADD AX, CX
ADC DX, BX
执行第一条指令后:
(AX)=0D389H, SF=1, ZF=0, CF=1, OF=0
执行第二条指令后:
(DX)=0008H, SF=0, ZF=0, CF=0, OF=0
3. 加1指令INC(INCrment)
INC OPRD
OPRD只能是 reg 和 mem,
不影响CF(即使进位CF也不置1)
该指令只要调整地址指针和计数器
4. 减法指令SUB(SUBtraction)
SUB OPRD1, OPRD2 (OPRD1 -= OPRD2)
如果两个数的符号相反而结果的符号与减数相同则OF=1,否则为0
SUB [SI+14H], 0136H
4336H – 0136H = 4200H 此时 SF = ZF = CF = OF = 0
41H – 5AH = 0E7H 此时 SF = CF = 1, ZF = OF = 0 产生借位
不要将减数取补.否则CF的结果相反.
5. 带借位减法指令SBB(SuBtraction with Borrow)
SBB OPRD1, OPRD2 (OPRD1 = OPRD1 – OPRD2 - CF)
6. 减1指令DEC(DECrement)
DEC OPRD
OPRD只能是 reg 和 mem, 相减时把操作数作为一个无符号数对待.
1. 取补指令NEG(NEGate)
NEG OPRD (OPRD = -OPRD)
如果在字节操作时对-128取补或者在字操作时对-32768取补,则操作数不变
但OF被置1,其他情况都为0
操作数为0时,求补后CF = 0,其他情况CF都为1
操作数可以是reg和mem
双字求补应先对高位求补.
NEG DX
NEG AX
SBB DX, 0
2. 比较指令CMP(CoMPare)
CMP OPRD1, OPRD2( OPRD1 – OPRD2 )
运算结果不送到OPRD1,但影响标志位
根据ZF是否置位判断两者是否相等
如果两数是无符号数,则可根据CF判断大小
如果两者是有符号数,则要根据SF和OF判断大小
CMP 15, BX (错的!!!) 改为 CMP BX, 15
① CMP REG, MEM ②CMP MEM, REG ③CMP REG, IMM
一、 乘除运算指令
乘除运算分为无符号数运算和有符号数运算
1. 乘法指令
乘法指令中,目的操作数总是隐含在AL或AX中,另一个操作数可以采用除立即数以外的任一种寻址方式
(1) 无符号数乘法指令MUL(MULtiply)
MUL OPRD
两个8位数相乘得到16位乘积存放在AX中,两个16位数得到的32位乘积存放在DX, AX中,DX存放高位字, AX存放低位字.
如果乘积结果的高半部分(AH或者DX)不等于0,则CF=OF=1,否则CF=OF=0,该指令对其他标志位无定义.
(2) 有符号数乘法指令IMUL(sIgned MULtiply)
IMUL OPRD
如果乘积结果的高半部分(AH或者DX)不是低半部分的符号扩展,则CF=OF=1,否则CF=OF=0,该指令对其他标志位无定义.
例: (AL)=0B4H, (BL)=11H,求执行指令MUL BL 和 IMUL BL的结果.
无符号: 0B4H × 11H = 0BF4H CF=OF=1
有符号(都进行符号位扩展): FFB4H × 0011H = FAF4H CF=OF=1
2. 除法指令
除法指令中,目的操作数总是隐含在AX(除数是8位)或者DX和AX(除数是16位)中,另一个操作数可以采用除立即数以外的任一种寻址方式,不影响标志位
(1) 无符号数除法指令DIV(DIVision)
DIV OPRD
字节操作: AX / OPRD的余数 → AH, AX / OPRD的商 → AL
字操作: (DX, AX) / OPRD的余数 → DX, (DX, AX) / OPRD的商 → AX
当除数为0,或者商太大时引起0号中断.
(2) 有符号数除法指令IDIV(sIgned DIVision)
IDIV OPRD
当除数为0,或者商太小(小于-127或者小于-32767) 或者商太大(大于127或者大于32767),则引起0号中断.
3. 符号扩展指令
(1) 字节转化为字指令CBW(Convert Byte to Word)
CBW
把AL的符号扩展到AH中
例子: MOV AX, 3487H ;AX=3487H, AH=34H, AL=87H
CBW ;AH=0FFH, AL=87H, AX=0FF87H
不影响标记位
(2) 字转换为双字指令CWD(Convert Word to Double word)
CWD
把AX的符号扩展到DX中
例子: MOV AX, 4567H ;AX=4567H
CBW ;AX=4567H, DX=0H
不影响标记位
计算如下表达式的值: (X*Y+Z-1024)/75假设其中的X,Y和Z均为16位带符号数,分别存放在名为XXX, YYY和ZZZ的变量单元中,计算结果的商保存在AX中,余数保存在DX中
MOV AX, XXX
IMUL YYY
MOV CX, AX
MOV BX, DX
MOV AX, ZZZ
CWD
ADD AX, CX ;低位相加
ADC DX, BX ;高位相加,考虑进位
SUB AX, 1024 ;低位相减
SBB DX, 0 ;高位相减,考虑借位
MOV CX, 75
IDIV CX
二、 逻辑运算和移位指令
1. 逻辑运算指令
(1) 否操作指令NOT
NOT OPRD
把OPRD取反,然后送回OPRD,不影响标记位
(2) 与操作指令AND
AND OPRD1, OPRD2
将两个操作数按位取与后送到OPRD1,执行后CF=OF=0,PF, ZF, SF由运算结果决定.AF未定义.
自己与自己相与使CF清零
(3) 或操作指令OR
OR OPRD1, OPRD2
将两个操作数按位取或后送到OPRD1,执行后CF=OF=0,PF, ZF, SF由运算结果决定.AF未定义.
(4) 异或操作指令XOR
XOR OPRD1, OPRD2
将两个操作数按位取异或后送到OPRD1,执行后CF=OF=0,PF, ZF, SF由运算结果决定.AF未定义.
自己与自己异或,结果为0,并使CF清0
(5) 测试指令TEST
TEST OPRD1, OPRD2
两个操作数按位取与,但结果不回送. 执行后CF=OF=0,PF, ZF, SF由运算结果决定.AF未定义.
例如要检查AL中的第6位或第2位是否有1.则可以使用指令
TEST AL, 01000100B
如果第6位和第2位全为0,则ZF=1,否则ZF=0(搞错了..结果是0的时候ZF=1)
2. 一般移位指令
OPRD可以是reg或者mem
移位超过1位的,把移位数放到CL中
移位只有1位的,直接移位
(1) 算术左移或逻辑左移指令SAL/SHL(Shift Arithmetic Left 或 Shift logic Left)
SAL OPRD, m(有符号数) 或者 SHL OPRD, m(无符号数) (两者等价)
左移m位,右边用0补足, 移出的最后一位进入标志位CF, AF未定义
MOV AL, 8CH
SHL AL, 1 ; AL=18H, CF=1, PF=1, ZF=0, SF=0, OF=1
MOV CL, 6
SHL AL, CL ; AL=0, CF=0, PF=1, ZF=1, SF=0, OF=0
把AL中的内容乘10,结果放到AX中
XOR AH, AH
SHL AL, 1
MOV BX, AX
SHL AX, 1
SHL AX, 1
ADD AX, BX
(2) 算术右移指令SAR(Shift Arithmetic Right)
SAR OPRD, m
该指令将操作数右移m位,左边用符号位补全, 移出的最后一位进入CF. AF未定义
(3) 逻辑右移指令SHR(Shift logic Right)
SHR OPRD, m
该指令将操作数右移m位,左边用0补全,移出的最后一位进入CF. AF未定义
3. 循环移位指令
ROL OPRD, m ;循环左移
ROR, OPRD, m ;循环右移
RCL, OPRD, m ;带进位循环右移
RCR, OPRD, m ;带进位循环左移
这些指令只影响CF和OF, OPRD可以是reg或者mem
操作数可以复原
例题:把AL的最低位送入BL的最低位,保持AL不变.
ROR BL, 1
ROR AL, 1
RCL BL, 1
ROL AL, 1
例题:双字左移4位
MOV CL, 4
SHL DX, CL
MOV BL, AH
SHL AX, CL
SHR BL, CL
OR DL, BL
三、 转移指令
1. 无条件转移指令
(1) 无条件段内直接转移指令
JMP 标号(地址差)(把地址差加到IP上)
指令操作码 |
地址差 |
段内无条件直接转移指令中的地址差如果用一个字节表示,就成为短转移(JMP NEAR PTR PROG).如果用一个字表示,就成为近转移(JMP SHORT PROG).
(2) 无条件段内间接转移指令
JMP OPRD
不改变段值,把操作数OPRD的内容的值给IP.OPRD是reg16或者mem16
例题: JMP WORD PTR [1234H]
(3) 无条件段间直接转移指令
JMP FAR PTR 标号(另一个代码段)
指令操作码 |
目标地址偏移 |
目标地址段值 |
把指令中包含的目标地址的段值和偏移分别置入CS和IP, 绝对转移.
(4) 无条件段间间接转移指令
JMP OPRD(双字的存储单元)
JMP DWORD PTR [1234H] ;低字内容送给IP,高字内容送给CS
2. 条件转移指令
所有条件转移都是段内转移,不影响标记位.
指令格式 |
转移条件 |
转移说明 |
JZ/JE |
ZF=1 |
等于 |
JNZ/JNE |
ZF=0 |
不等于 |
JS |
SF=1 |
负数 |
JNS |
SF=0 |
正数 |
JO |
OF=1 |
溢出 |
JNO |
OF=0 |
无溢出 |
JP/JPE |
PF=1 |
偶 |
JNP/JPO |
PF=0 |
奇 |
JB/JNAE/JC |
CF=1 |
低于 |
JNB/JAE/JNC |
CF=0 |
不低于 |
JBE/JNA |
(CF OR ZF)=1 |
不高于 |
JNBE/JA |
(CF OR ZF)=0 |
高于 |
JL/JNGE |
(SF XOR OF)=1 |
小于 |
JNL/JGE |
(SF XOR OF)=0 |
不小于 |
JLE/JNG |
((SF XOR OF) OR ZF)=1 |
不大于 |
JNLE/JG |
((SF XOR OF) OR ZF)=0 |
大于 |
例题: 在存储器中有一个首地址位ARRAY的N字数组,要求测试其中正数,零,以及负数的个数.正数的个数放在DI中,零的个数放在SI中,并根据N – (DI) – (SI)求得的个数放在AX中,如果有负数则转移到VAL中去执行
MOV BX, 0
MOV DI, BX
MOV SI, BX
MOV CX, N
AGAIN: CMP ARRAY[BX], 0
JLE LESS
INC DI
JMP SHORT NEXT
LESS: JL NEXT
INC SI
NEXT: ADD BX, 2
DEC CX
JNZ AGAIN
MOV AX, N
SUB AX, DI
SUB AX, SI
JL VAL ;JNZ VAL
VAL: ………..
3. 循环指令
属于段内转移,采用相对转移的方式.即通过一个IP加上一个以字节表示的地址差.
(1) 计数循环指令LOOP
LOOP 标号
这条指令使CX的值减一
(2) 等于/全零循环指令LOOPE/LOOPZ
LOOPE/LOOPZ 标号
当CX不为0而且ZF=1时跳转,即如果还可以循环的时候两者相等则继续循环.
(3) 不等于/非零循环指令LOOPNE/LOOPNZ
LOOPNE/LOOPNZ 标号
(4) 跳转指令JCXZ
JCXZ 标号
当CX=0时跳转到标号,否则顺序执行.通常该指令用在循环开始前,以便再循环次数为0时跳过循环体.