? 指令系统一组指令的集合第 3章 80x86的指令系统和寻址方式操作码 操作数,.,操作数指令
寻址方式与数据有关的寻址方式与转移地址有关的寻址方式
1,8086的寻址方式与数据有关的寻址方式,以 MOV指令为例
立即寻址 MOV AX,3069H
寄存器寻址 MOV AL,BH
直接寻址 MOV AX,[ 2000H ]
寄存器间接寻址 MOV AX,[ BX ]
寄存器相对寻址 MOV AX,COUNT [ SI ]
基址变址寻址 MOV AX,[ BP ] [ DI ]
相对基址变址寻址 MOV AX,MASK [ BX ] [ SI ]
存储器寻址
(1) 立即寻址方式 * —— 操作数在指令中给出指令格式,MOV AL,5
MOV AX,3064H
MOV AL,‘A’
* 只能用于 SRC 字段 MOV 40H,AL?
* SRC 和 DST 的字长一致
MOV AH,3064H?
(2) 寄存器寻址方式 * — 操作数在指定的寄存器中
MOV AX,BX
MOV AL,BH
MOV AX,3064H
* 字节寄存器只有 AH AL BH BL CH CL DH DL
* SRC 和 DST 的字长一致 MOV AH,BX?
* CS 不能用 MOV 指令改变 MOV CS,AX?
(3) 直接寻址方式 * — 有效地址 EA由指令直接给出例,MOV AX,[ 2000H ]
EA=2000H,假设 (DS)=3000H,那么 PA=32000H
* 隐含的段为数据段 DS
* 可使用段跨越前缀 MOV AX,ES,[2000H]
* 操作数地址可由变量(符号地址)表示,但要注意
VALUE DB 10 变量的属性
MOV AH,VALUE
MOV AX,VALUE?
MOV AX,WORD PTR VALUE?
50
30
32000
AH AL
30 50
(AX) = 3050H
(4) 寄存器间接寻址 * — EA 在基址寄存器 (BX/BP)
或变址寄存器 (SI/DI) 中
MOV AX,[BX] PA = 16d? (DS) + (BX)
MOV AX,ES:[BX] PA = 16d? (ES) + (BX)
MOV AX,[BP] PA = 16d? (SS) + (BP)
* 不允许使用 AX,CX,DX 存放 EA
MOV AX,[CX]?
* SRC 和 DST 的字长一致
MOV DL,[ BX ] ; [BX]指示一个字节单元
MOV DX,[ BX ] ; [BX]指示一个字单元
* 适于数组、字符串、表格的处理
(5) 寄存器相对寻址方式 *
指令格式,MOV AX,COUNT[SI] 或
MOV AX,[COUNT+SI]
假设 (DS)=3000H,(SI)=2000H,COUNT=3000H,
则,PA = 35000H
假设 (35000H)=1234H,那 么 (AX)=1234H
* 适于数组、字符串、表格有效地址 =
(BX)
(BP) 8位
(SI) 16位
(DI)
+ 位移量
(6) 基址变址寻址方式 *
指令格式,MOV AX,[BX] [DI]
MOV AX,[BX+DI]
MOV AX,ES:[BX] [SI]
* 适于数组、字符串、表格的处理
* 必须是一个基址寄存器和一个变址寄存器的组合
MOV AX,[BX] [BP]?
MOV AX,[SI] [DI]?
有效地址 = (BX) (SI)
(BP) (DI)
+
( 7 ) 相对基址变址寻址方式
MOV AX,MASK [BX] [SI]
或 MOV AX,MASK [BX+SI]
或 MOV AX,[MASK+BX+SI]
有效地址 = (BX) (SI) 8位
(BP) (DI) 16位
+ + 位移量访问存储器的方式 默认的段寄存器 可跨越的段寄存器 偏移地址取指令 CS 无 IP
堆栈操作 SS 无 SP
一般数据访问 DS CS ES SS 有效地址 EA
BP作为基址的寻址 SS CS DS ES BP
串操作的源操作数 DS CS ES SS SI
串操作的目的操作数 ES 无 DI
段 寄 存 器 的 使 用 规 定例,编写一段显示字符串 STRING的程序
DATA SEGMENT
STRING DB ‘ HAPPY NEW YEAR! ’,0DH,0AH,‘ $ ’
COUNT DW 17
DATA ENDS [字符串 存储情况 ]
( 1 ) 直接寻址
mov dl,string
mov ah,2
int 21h (P335) ; 显示字符‘ H’
mov dl,string+1
mov ah,2
int 21h ; 显示字符‘ A’
:
:
( 2 ) 寄存器间接寻址
mov cx,count ; mov cx,17
mov bx,offset string ; string的偏址? bx
Next,mov dl,[bx]
mov ah,2
int 21h ; 显示一个字符
inc bx
loop next ; 循环指令
( 3 ) 寄存器相对寻址
mov cx,count ; mov cx,17
mov si,0
Next,mov dl,string[si] ; mov dl,[string+si]
mov ah,2
int 21h ; 显示一个字符
inc si
loop next ; 循环指令
( 4 ) 基址变址寻址
mov cx,count ; mov cx,17
mov bx,offset string ; string的偏址? bx
mov si,0
Next,mov dl,[bx] [si] ; mov dl,[bx+si]
mov ah,2
int 21h ; 显示一个字符
inc si
loop next ; 循环指令
( 5 ) DOS 显示字符串功能
mov dx,offset string ; string的偏址? dx; lea dx,string
mov ah,9
int 21h ; 显示一串字符
80x86 新增的寻址方式
EA= (基址寄存器 ) + (变址寄存器 )? 比例因子 + 位移量
( 1 ) 比例变址寻址方式例,MOV EAX,COUNT [ ESI? 4 ]
(2) 基址比例变址寻址方式例,MOV ECX,[ EAX ][ EDI? 4 ]
(3) 相对基址比例变址寻址方式例,MOV EAX,TABLE [ EBP ][ EDI? 4 ]
▲ 16位和 32位寻址的差异地址成分 16位寻址 32位寻址基址寄存器 BX,BP 任何 32位通用寄存器变址寄存器 SI,DI 除 ESP外的任何 32位通用寄存器比例因子 1 1,2,4,8
与转移地址有关的寻址方式:
段内寻址段内直接寻址 JMP NEAR PTR NEXT
段内间接寻址 JMP TABLE [ BX ]
段间寻址段间直接寻址 JMP FAR PTR NEXT
段间间接寻址 JMP DWORD PTR [ BX ]
用来确定转移指令及转移指令的转向地址 。
(1) 段内直接寻址转向的有效地址 = 当前 (IP) + 位移量 (8bit/16bit)
例,JMP NEAR PTR NEXT 近转移 -32768 ~ +32767
JMP SHORT NEXT 短转移 -128 ~ +127
(2) 段内间接寻址转向的有效地址是一个寄存器或存储单元的内容。
( 可用除立即数以外的任何一种数据寻址方式得到 )
例,TABLE = 20A2H (BX) = 1256H (SI) = 528EH
(DS) = 2000H (232F8H) = 3280H (264E4H) = 2450H
JMP BX ; (IP)=1256H
JMP TABLE[BX]
JMP WORD PTR TABLE[BX] ; (IP)=3280H
JMP [BX][SI]
JMP WORD PTR [BX][SI] ; (IP)=2450H
code1 segment
……
jmp far ptr next
……
code1 ends
code2 segment
……
next,…,..
……
code2 ends
(3) 段间直接寻址用指令中提供的转向段地址和偏移地址取代 CS 和 IP
例,
(4) 段间间接寻址用存储器中的两个相继字的内容取代 CS 和 IP
( 存储单元的地址可用存储器寻址方式得到 )
例:
JMP DWORD PTR [INTERS+BX]
PA=(DS)× 10H+ (BX) + INTERS
(PA+1,PA)→IP
(PA+3,PA+2) →CS
数据传送指令
算术指令
逻辑指令
串处理指令
控制转移指令
处理机控制与杂项操作指令
2,8086的指令系统重点关注:
指令的汇编格式
指令的基本功能
指令支持的寻址方式
指令的执行对标志位的影响
指令的特殊要求
数据传送指令,
通用数据传送指令
MOV,PUSH,POP,XCHG
累加器专用传送指令
IN,OUT,XLAT
地址传送指令
LEA,LDS,LES
标志寄存器传送指令
LAHF,SAHF,PUSHF,POPF
类型转换指令
CBW,CWD
传送指令,MOV DST,SRC
执行操作,(DST)? (SRC)
注意,
* DST,SRC 不能同时为段寄存器 MOV DS,ES?
* 立即数不能直接送段寄存器 MOV DS,2000H?
* DST 不能是立即数和 CS
* DST,SRC 不能同时为存储器寻址
* 不影响标志位
通用数据传送指令
MOV AX,DSEG
MOV DS,AX
进栈指令,PUSH SRC
执行操作,(SP)? (SP) – 2
( (SP)+1,(SP) )? (SRC)
出栈指令,POP DST
执行操作,(DST)? ( (SP)+1,(SP) )
(SP)? (SP) + 2
堆栈,‘ 先进后出 ’ 的存储区,段地址存放在 SS中,
SP在任何时候都指向栈顶,进出栈后自动修改 SP。
注意,
* 堆栈操作必须以字为单位 。
* 不影响标志位
* 不能用立即寻址方式 PUSH 1234H?
* DST不能是 CS POP CS?
例:假设 (AX) = 2107 H,执行 PUSH AX
* *
* *
* *
* *
( SP)?
PUSH AX 执行前
( SP)?
* *
* *
* *
* *
07H
21H
低地址高地址
PUSH AX 执行后进栈方向
( SP)?
* *
* *
* *
* *
07H
21H
POP BX 执行 前
( SP)? * *
* *
* *
* *
低地址高地址
POP BX 执行后
(BX) = 2107H
例,POP BX
出栈方向例,PUSH DS
SUB AX,AX
PUSH AX
……
……
RET
例,PUSH AX
PUSH BX
PUSH CX
…… ;其间用到 AX,BX,CX
POP CX ; 后进先出
POP BX
POP AX
交换指令,XCHG OPR1,OPR2
执行操作,(OPR1)? (OPR2)
注意,
* 不影响标志位
* 不允许使用段寄存器例,XCHG BX,[ BP+SI ]
XCHG AL,BH
累加器专用传送指令 ( 只限使用 AX或 AL)
输入指令 IN ( I/O? CPU)
长格式,IN AL,PORT ( 字节 )
IN AX,PORT ( 字 )
执行操作,(AL)? ( PORT ) ( 字节 )
(AX)? ( PORT+1,PORT )( 字 )
短格式,IN AL,DX (字节) (端口号 >255)
IN AX,DX (字)
执行操作,(AL)? ( (DX) ) (字节)
(AX)? ( (DX)+1,(DX) )(字)
输出指令 OUT ( CPU? I/O)
长格式,OUT PORT,AL (字节)
OUT PORT,AX (字)
执行操作,( PORT )? (AL) (字节)
( PORT+1,PORT )? (AX)(字)
短格式,OUT DX,AL (字节) (端口号 >255)
OUT DX,AX (字)
执行操作,( (DX) )? (AL) (字节)
( (DX)+1,(DX) )? (AX)(字)
注意,
* 不影响标志位
* 前 256个端口号 00H~FFH可直接在指令中指定(长格式)
* 如果 端口号?256,端口号?DX(短格式)
例,IN AX,28H
MOV DATA_WORD,AX
例,MOV DX,3FCH
IN AX,DX
例,OUT 5,AL
例:测试某状态寄存器(端口号 27H)的第 2位是否为 1
IN AL,27H
TEST AL,00000100B
JNZ ERROR ;若 第 2位为 1,转 ERROR处理例,Sound程序
mov dx,100
in al,61h
and al,11111100b
sound,xor al,2 ; 1 0 1
out 61h,al ; ON OFF ON
mov cx,140h ;脉宽
Wait1,loop wait1
dec dx
jne sound
设备控制寄存器端口 61H 1 / 0 0
控制其它外部设备与门 放大器
2号定时器门控
1 0
(BX)? 30 H F0040
31 H F0041
(AL) = 3 32 H F0042
33 H F0043
TABLE
(DS)=F000H
换码指令,XLAT 或 XLAT OPR
执行操作,(AL)? ( (BX) + (AL) )
例,MOV BX,OFFSET TABLE ; (BX)=0040H
MOV AL,3
XLAT TABLE
指令执行后 (AL)=33H
注意,
* 不影响标志位
* 字节表格 (长度不超过 256)
首地址? (BX)
* 需转换的代码位移量? (AL)
地址传送指令有效地址送寄存器指令,LEA REG,SRC
执行操作,(REG)? SRC
指针送寄存器和 DS指令,LDS REG,SRC
执行操作,(REG)? (SRC)
(DS)? (SRC+2)
相继二字? 寄存器,DS
指针送寄存器和 ES指令,LES REG,SRC
执行操作,(REG)? (SRC)
(ES)? (SRC+2)
相继二字? 寄存器,ES
例,LEA BX,[BX+SI+0F62H]
LDS SI,[10H]
LES DI,[BX]
40 H
00 H
00 H
30 H
TABLE
(DS):1000H
MOV BX,TABLE ; (BX)=0040H
MOV BX,OFFSET TABLE ; (BX)=1000H
LEA BX,TABLE ; (BX)=1000H
LDS BX,TABLE ; (BX)=0040H; (DS)=3000H
LES BX,TABLE ; (BX)=0040H; (ES)=3000H
注意,
* 不影响标志位
* REG 不能是 段寄存器
* SRC 必须为存储器寻址方式
标志寄存器传送指令标志送 AH指令,LAHF
执行操作,(AH)? (FLAGS的低字节 )
AH送标志寄存器指令,SAHF
执行操作,(FLAGS的低字节 )? (AH)
标志进栈指令,PUSHF
执行操作,(SP)? (SP) - 2
( (SP)+1,(SP) )? (FLAGS)
标志出栈 指令,POPF
执行操作,(FLAGS)? ( (SP)+1,(SP) )
(SP)? (SP) + 2
* 影响标志位
类型转换指令 (符号扩展指令 )
CBW AL? AX
执行操作,若 (AL)的最高有效位为 0,则 (AH)= 00H
若 (AL)的最高有效位为 1,则 (AH)= FFH
CWD AX? (DX,AX)
执行操作:若 (AX)的最高有效位为 0,则 (DX)= 0000H
若 (AX)的最高有效位为 1,则 (DX)= FFFFH
例,(AX) = 0BA45H
CBW ; (AX)=0045H
CWD ; (DX)=0FFFFH (AX)=0BA45H
注意,* 无操作数指令
* 隐含对 AL 或 AX 进行符号扩展
* 不影响 条件标志位算术指令:
加法指令
ADD,ADC,INC
减法指令
SUB,SBB,DEC,NEG,CMP
乘法指令
MUL,IMUL
除法指令
DIV,IDIV
十进制调整指令
DAA,DAS、
AAA,AAS,AAM,AAD
加法指令加法指令,ADD DST,SRC
执行操作,(DST)? (SRC) + (DST)
带进位加法指令,ADC DST,SRC
执行操作,(DST)? (SRC) + (DST) + CF
加 1指令,INC OPR
执行操作,(OPR)? (OPR) + 1
注意,
* 除 INC指令 不影响 CF标志外,均对条件标志位有影响。
加法指令对 条件标志位 的影响
CF 位表示 无符号数 相加的溢出。
OF 位表示 带符号数 相加的溢出。
1 结果为负
0 否则SF=
1 结果为 0
0 否则ZF=
1 和的最高有效位 有 向高位的进位
0 否则CF=
1 两个操作数符号相同,而结果符号与之相反
0 否则OF=
举例,n=8 bit 带符号数 (-128~127),无符号数 (0~255)
0 0 0 0 0 1 0 0
+ 0 0 0 0 1 0 1 1
0 0 0 0 1 1 1 1
带,(+4)+(+11)=+15 OF=0
无,4+11=15 CF=0
带符号数和无符号数都不溢出
0 0 0 0 1 0 0 1
+ 0 1 1 1 1 1 0 0
1 0 0 0 0 1 0 1
带,(+9)+(+124)=-123 OF=1
无,9+124=133 CF=0
带符号数溢出无符号数溢出
0 0 0 0 0 1 1 1
+ 1 1 1 1 1 0 1 1
1 0 0 0 0 0 0 1 0
带,(+7)+(-5)=+2 OF=0
无,7+251=2 CF=1
带符号数和无符号数都溢出
1 0 0 0 0 1 1 1
+ 1 1 1 1 0 1 0 1
1 0 1 1 1 1 1 0 0
带,(-121)+(-11)=+124 OF=1
无,135+245=124 CF=1
无符号数的溢出表现为加法运算结果向高位的进位,减法溢出则是不够减时发生的向高位的借位。
对有符号数,同号相加结果变位,肯定发生溢出( OF=1),异号相加不可能产生溢出。
例:双精度数的加法 0002F365H+00058100H
(DX) = 0002H (AX) = 0F365H
(BX) = 0005H (CX) = 8100H
指令序列 ADD AX,CX ; (1)
ADC DX,BX ; (2)
(1) 执行后,(AX) = 7465H
CF=1 OF=1 SF=0 ZF=0
(2) 执行后,(DX) = 0008H
CF=0 OF=0 SF=0 ZF=0
减法指令减法指令,SUB DST,SRC
执行操作,(DST)? (DST) - (SRC)
带借位减法指令,SBB DST,SRC
执行操作,(DST)? (DST) - (SRC) - CF
减 1指令,DEC OPR
执行操作,(OPR)? (OPR) - 1
求补指令,NEG OPR
执行操作,(OPR)? - (OPR)
比较指令,CMP OPR1,OPR2
执行操作,(OPR1) - (OPR2)
注意,
* 除 DEC指令 不影响
CF标志外,均对条件标志位有影响。
减法指令对条件标志位 ( CF/OF/ZF/SF) 的影响:
CF 位表示 无符号数 减法的溢出。
OF 位表示 带符号数 减法的溢出。
1 被减数的最高有效位 有 向高位的借位
0 否则CF=
1 两个操作数符号相反,而结果的符号与减数相同
0 否则OF=
1 减法转换为加法运算时 无 进位
0 否则CF=

NEG 指令对 CF/OF的影响
0 操作数为 0
1 否则CF =
1 操作数为 -128 (字节运算) 或操作数为 -32768 (字运算)
0 否则
OF =
0 0 0 1
1 1 1 0
+ 0 0 0 1
1 1 1 1
NEG 指令对 CF/OF的影响
0 操作数为 0
1 否则CF =
1 操作数为 -128 (字节运算) 或操作数为 -32768 (字运算)
0 否则
OF =
0 0 0 0
1 1 1 1
+ 0 0 0 1
1 0 0 0 0
1 0 0 0
0 1 1 1
+ 0 0 0 1
1 0 0 0
例,x,y,z 均为双精度数,分别存放在地址为 X,X+2;
Y,Y+2; Z,Z+2的存储单元中,用指令序列实现
w? x + y + 24 - z,并用 W,W+2单元存放 w
MOV AX,X
MOV DX,X+2
ADD AX,Y
ADC DX,Y+2 ; x+y
ADD AX,24
ADC DX,0 ; x+y+24
SUB AX,Z
SBB DX,Z+2 ; x+y+24-z
MOV W,AX
MOV W+2,DX ; 结果存入 W,W+2单元
乘法指令无符号数乘法指令,MUL SRC
带符号数乘法指令,IMUL SRC
执行操作:
字节操作数 (AX)? (AL) * (SRC)
字操作数 (DX,AX)? (AX) * (SRC)
注意,
AL (AX) 为隐含的乘数寄存器。
AX (DX,AX) 为隐含的乘积寄存器。
SRC不能为立即数。
除 CF和 OF外,对条件标志位无定义 。
乘法指令对 CF/OF 的影响:
例,(AX) = 16A5H,(BX) = 0611H
(1) IMUL BL ; (AX)? (AL) * (BL); A5H*11H = F9F5H; (AX) = 0F9F5H CF=OF=1
(2) MUL BX ; (DX,AX)? (AX) * (BX); 16A5H*0611H=0089 5EF5H; (DX)=0089H (AX)=5EF5H CF=OF=1
00 乘积的高一半为零
11 否则MUL指令,CF,OF =
00 乘积的高一半是低一半的符号扩展
11 否则IMUL指令,CF,OF =
1010 0101
0101 1011
除法指令无符号数除法指令,DIV SRC
带符号数除法指令,IDIV SRC
执行操作:
字节操作 (AL)? (AX) / (SRC) 的商
(AH)? (AX) / (SRC) 的余数字操作 (AX)? (DX,AX) / (SRC) 的商
(DX)? (DX,AX) / (SRC) 的余数注意,* AX (DX,AX) 为隐含的被除数寄存器。
* AL (AX) 为隐含的商寄存器。
* AH (DX) 为隐含的余数寄存器。
* SRC不能为立即数。
* 对所有条件标志位均无定义。 如何判别结果有效?
例,x,y,z,v 均为 16位带符号数,计算
( v - ( x*y + z – 540 ) ) / x
MOV AX,X
IMUL Y ; x*y →( DX,AX)
MOV CX,AX
MOV BX,DX ; ( DX,AX) → ( BX,CX)
MOV AX,Z
CWD ; Z →( DX,AX)
ADD CX,AX
ADC BX,DX ; x*y+z →( BX,CX)
SUB CX,540
SBB BX,0 ; x*y+z-540
MOV AX,V
CWD ; V →( DX,AX)
SUB AX,CX
SBB DX,BX ; v-(x*y+z-540)
IDIV X ; (v-(x*y+z-540))/x→( AX)
余数 →( DX)
十进制调整指令
BCD码:用二进制编码的十进制数,又称 二 --十进制数压缩的 BCD码:用 4 位二进制数表示 1 位十进制数
( 59 )10 = ( 111011 )2
例,( 59 )10 = ( 0101 1001 )BCD
非压缩的 BCD码:用 8 位二进制数表示 1 位十进制数例,( 59 )10 = ( 0000 0101 0000 1001 )BCD
数字的 ASCII 码是一种 非压缩的 BCD 码
DIGIT ASCII BCD
0 30H 0011 0000
1 31H 0011 0001
2 32H 0011 0010
… … …
9 39H 0011 1001
例:写出 ( 3590 )10的压缩 BCD 码和非压缩 BCD码,并分别 把它们存入数据区 PAKED 和 UNPAK
压缩 BCD,( 3590 )10= ( 0011 0101 1001 0000 )BCD
非压缩 BCD:
( 3590 )10= ( 00000011 00000101 00001001 00000000 )BCD
PAKED 90H
35H
UNPAK 00H
09H
05H
03H
问题的提出:
十进制调整指令
19 压缩 BCD,0001 1001
27 0010 0001 + 110
+ 08 + 0000 1000
(0010 0111)BCD
因此:两数相加,过 9加 6!
AF=1
( 1)压缩的 BCD码调整指令
● DAA 加法的十进制调整指令
● DAS 减法的十进制调整指令
( 2)非压缩的 BCD码调整指令
● AAA 加法的 ASCII码调整指令
● AAS 减法的 ASCII码调整指令
● AAM 乘法的 ASCII码调整指令
● AAD 除法的 ASCII码调整指令压缩 BCD运算举例:
( 1) MOV AL,BCD1 ; BCD1=34H
ADD AL,BCD2 ; BCD2=59H,(AL)=8DH
DAA ; 8DH+06H=93H
MOV BCD3,AL ; BCD3=93H
( 2) MOV AL,BCD1 ; BCD1=34H
SUB AL,BCD2 ; BCD2=59H,(AL)=0DBH
DAS ; 0DBH- 60H- 06H=75H
MOV BCD3,AL ; BCD3= 75 = - 25
逻辑指令:
逻辑运算指令
AND,OR,NOT,XOR,TEST
移位指令
SHL,SHR,SAL,SAR、
ROL,ROR,RCL,RCR
逻辑非指令,NOT OPR * OPR不能为立即数执行操作,(OPR) (OPR) * 不影响标志位逻辑与指令,AND DST,SRC
执行操作,(DST)? (DST)? (SRC)
逻辑或指令,OR DST,SRC
执行操作,(DST)? (DST)? (SRC)
异或指令,XOR DST,SRC
执行操作,(DST)? (DST)? (SRC)
测试指令,TEST OPR1,OPR2
执行操作,(OPR1)? (OPR2)
CF OF SF ZF PF AF
0 0 * * * 无定义根据运算结果设置
逻辑运算指令例:屏蔽 AL的第 0,1两位
AND AL,0FCH
例:置 AL的第 5位为 1
OR AL,20H
例:使 AL的第 0,1位变反
XOR AL,3
例:测试某些位是 0是 1
TEST AL,1
JZ EVEN
* * * * * * * *
OR 0 0 1 0 0 0 0 0
* * 1 * * * * *
* * * * * * 0 1
XOR 0 0 0 0 0 0 1 1
* * * * * * 1 0
* * * * * * * *
AND 1 1 1 1 1 1 0 0
* * * * * * 0 0
* * * * * * * *
AND 0 0 0 0 0 0 0 1
0 0 0 0 0 0 0 *
逻辑左移 SHL OPR,CNT
逻辑右移 SHR OPR,CNT
算术左移 SAL OPR,CNT( 同逻辑左移 )
算术右移 SAR OPR,CNT
CF 0
0 CF
CF
移位指令循环左移 ROL OPR,CNT
循环右移 ROR OPR,CNT
带进位循环左移 RCL OPR,CNT
带进位循环右移 RCR OPR,CNT
CF
CF
CF
CF
注意,
* OPR可用除立即数以外的任何寻址方式
* CNT=1,SHL OPR,1
CNT>1,MOV CL,CNT
SHL OPR,CL ; 以 SHL为例
* 条件标志位:
CF = 移入的数值
OF=1 CNT=1时,最高有效位的值发生变化
OF=0 CNT=1时,最高有效位的值不变移位指令:
SF,ZF,PF 根据移位结果设置,AF无定义循环移位指令:
不影响 SF,ZF,PF,AF
例,(AX)= 0012H,(BX)= 0034H,把它们装配成 (AX)= 1234H
例,(BX) = 84F0H
(1) (BX) 为无符号数,求 (BX) / 2
SHR BX,1 ; (BX) = 4278H
(2) (BX) 为带符号数,求 (BX) × 2
SAL BX,1 ; (BX) = 09E0H,OF=1
(3) (BX) 为带符号数,求 (BX) / 4
MOV CL,2
SAR BX,CL ; (BX) = 0E13CH
MOV CL,8
ROL AX,CL
ADD AX,BX
MOV CH,4 ; 循环次
MOV CL,4 ; 移位 次数
NEXT,
ROL BX,CL
MOV AX,BX
AND AX,0FH
PUSH AX
DEC CH
JNZ NEXT 0008
0004
000F
0000? (SP)
(3) (BX)=84F0H,把 (BX)中的 16 位数每 4 位压入堆栈串处理指令:
设置方向标志指令
CLD,STD
串处理指令? 串重复前缀
MOVSB / MOVSW REP
STOSB / STOSW REPE / REPZ
LODSB / LODSW REPNE / REPNZ
CMPSB / CMPSW
SCASB / SCASW
与 REP 配合工作的 MOVS / STOS / LODS
REP
执行操作:
(1)如 (CX)=0 则退出 REP,否则转 (2)
(2)(CX)? (CX) –1
(3)执行 MOVS / STOS / LODS
(4)重复 (1) ~ (3)
MOVS 串传送指令:
MOVS DST,SRC
MOVSB ( 字节 )
MOVSW ( 字 )
例,MOVS ES,BYTE PTR [DI],DS,[SI]
执行操作:
(1) ((DI)) ← ((SI))
(2) 字节操作,(SI)← (SI)± 1,(DI)← (DI)± 1
字操作,(SI)← (SI)± 2,(DI)← (DI)± 2
方向标志 DF=0 时用 +,DF=1 时用 - 。
REP MOVS:将数据段中的整串数据传送到附加段中 。
源串 ( 数据段 ) → 目的串 ( 附加段 )
执行 REP MOVS 之前,应先做好:
(1) 源串首地址(末地址) → SI
(2) 目的串首地址(末地址) → DI
(3) 串长度 → CX
(4) 建立方向标志
( CLD 使 DF=0,STD 使 DF=1 )
( SI)( DI)
DF=0 DF=1
数据段 附加段
( SI)( DI)
data segment
mess1 db ‘personal_computer’
data ends
extra segment
mess2 db 17 dup (?)
extra ends
code segment
mov ax,data
mov ds,ax
mov ax,extra
mov es,ax
lea si,mess1
lea di,mess2
mov cx,17
cld
rep movsb

code ends
lea si,mess1+16
lea di,mess2+16
mov cx,17
std
rep movsb
data segment
mess1 db ‘personal_computer’
mess2 db 17 dup (?)
data ends
code segment
mov ax,data
mov ds,ax
mov es,ax
lea si,mess1
lea di,mess2
mov cx,17
cld
rep movsb

code ends
STOS 存入串指令:
STOS DST
STOSB ( 字节 )
STOSW ( 字 )
执行操作:
字节操作,((DI))← (AL),(DI)← (DI)± 1
字操作,((DI))← (AX),(DI)← (DI)± 2
例:把 附加段 中的 10 个字节缓冲区置为 20H
lea di,mess2
mov al,20H
mov cx,10
cld
rep stosb
lea di,mess2
mov ax,2020H
mov cx,5
cld
rep stosw
LODS 从串取指令:
LODS SRC
LODSB ( 字节 )
LODSW ( 字 )
执行操作:
字节操作,(AL)← ((SI)),(SI)← (SI)± 1
字操作,(AX)← ((SI)),(SI)← (SI)± 2
注意,
* LODS 指令一般不与 REP 联用
* 源串一般在数据段中(允许使用段跨越前缀来修改),
目的串必须在附加段中
* 不影响条件标志位与 REPE / REPZ( REPNE / REPNZ) 配合工作的
CMPS 和 SCAS
REPE / REPZ
REPNE / REPNZ
执行操作:
(1) 如 (CX)=0 或 ZF=0 (ZF=1) 则退出串操作,
否则转 (2)
(2) (CX)←(CX) -1
(3) 执行 CMPS / SCAS
(4) 重复 (1) ~ (3)
CMPS 串比较指令:
CMPS SRC,DST
CMPSB ( 字节 )
CMPSW ( 字 )
执行操作:
(1) ((SI)) - ((DI))
根据比较结果置条件标志位:相等 ZF=1
不等 ZF=0
(2) 字节操作,(SI)← (SI)± 1,(DI)← (DI)± 1
字操作,(SI)← (SI)± 2,(DI)← (DI)± 2
SCAS 串扫描指令:
SCAS DST
SCASB (字节)
SCASW (字)
执行操作:
字节操作,(AL) - ((DI)),(DI)← (DI)± 1
字操作,(AX) - ((DI)),(DI)← (DI)± 2
例:从一个字符串中查找一个指定的字符
mess db ‘COMPUTER’
lea di,mess
mov al,‘T’
mov cx,8
cld
repne scasb
C
O
M
P
U
T
E
R
(di)?
(di):相匹配字符的下一个地址
(cx):剩下还未比较的字符个数
(di)?
( CX)=2
例:比较两个字符串,找出它们不相匹配的位置例:反向传送
lea si,mess1
lea di,mess2
mov cx,8
Cld
repe cmpsb
lea si,mess1+7
lea di,mess2+7
mov cx,8
STd
rep movsb
控制转移指令:
无条件转移指令
JMP
条件转移指令
JZ / JNZ,JE / JNE,JS / JNS,JO / JNO、
JP/ JNP,JB / JNB,JL / JNL,JBE / JNBE、
JLE / JNLE,JCXZ
循环指令
LOOP,LOOPZ/ LOOPE,LOOPNZ/ LOOPNE
子程序调用和返回指令
CALL,RET
中断与中断返回指令
INT,INTO,IRET
无条件转移指令:
段内直接短转移,JMP SHORT OPR
执行操作,(IP) ← (IP) + 8位位移量段内直接近转移,JMP NEAR PTR OPR
执行操作,(IP)← (IP) + 16位位移量段内间接转移,JMP WORD PTR OPR
执行操作,(IP) ← (EA)
段间直接远转移,JMP FAR PTR OPR
执行操作,(IP)← OPR 的段内偏移地址
(CS) ← OPR 所在段的段地址段间间接转移,JMP DWORD PTR OPR
执行操作,(IP) ← (EA)
(CS) ← (EA+2)
条件转移指令:
注意:只能使用段内直接寻址的 8位位移量
(1) 根据单个条件标志的设置情况转移格式 测试条件
JZ(JE) OPR ZF = 1
JNZ(JNE) OPR ZF = 0
JS OPR SF = 1
JNS OPR SF = 0
JO OPR OF = 1
JNO OPR OF = 0
JP OPR PF = 1
JNP OPR PF = 0
JC OPR CF = 1
JNC OPR CF = 0
(2) 比较两个无符号数,并根据比较结果转移 *
格式 测试条件
< JB (JNAE,JC) OPR CF = 1
≥ JNB (JAE,JNC) OPR CF = 0
≤ JBE (JNA) OPR CF∨ ZF = 1
> JNBE (JA) OPR CF∨ ZF = 0
* 适用于地址或双精度数低位字的比较
(3) 比较两个带符号数,并根据比较结果转移 *
格式 测试条件
< JL (JNGE) OPR SF?OF = 1
≥ JNL(JGE) OPR SF?OF = 0
≤ JLE (JNG) OPR (SF?OF)∨ ZF = 1
> JNLE (JG) OPR (SF?OF)∨ ZF = 0
* 适用于带符号数的比较
(4) 测试 CX 的值为 0 则转移格式 测试条件
JCXZ OPR (CX)=0
例:如果 X>50,转到 TOO_HIGH ;否则 |X-Y| →
RESULT,如果溢出转到 OVERFLOW,
JG
JO
JNS
MOV AX,X
CMP AX,50
TOO_HIGH
SUB AX,Y
OVERFLOW
NONNEG
NEG AX
NONNEG,
MOV RESULT,AX
TOO_HIGH:
……
OVERFLOW,
……
例,?,?是双精度数,分别存于 DX,AX 及 BX,CX 中,
>? 时转 L1,否则转 L2
CMP DX,BX
JG L1
JL L2
CMP AX,CX
JA L1
L2,
……
L1,
……
循环指令:
注意:
1.CX 中存放循环次数
2,只能使用段内直接寻址的 8 位位移量
LOOP
LOOPZ / LOOPE
LOOPNZ / LOOPNE
执行步骤:
(1) (CX) ← (CX) – 1
(2) 检查是否满足测试条件,如满足则
(IP) ← (IP) + 8位位移量,实行循环;
不满足则 IP不变,退出循环 。
循环指令,LOOP OPR
测试条件,(CX)? 0
为零或相等时循环指令,LOOPZ(LOOPE) OPR
测试条件,ZF=1 且 (CX)? 0
不为零或不相等时循环指令,LOOPNZ(LOOPNE) OPR
测试条件,ZF=0 且 (CX)? 0
LOOP AGAIN DEC CXJNZ AGAIN
例:求首地址为 ARRAY 的 M 个字之和,
结果存入 TOTAL
MOV CX,M
MOV AX,0
MOV SI,AX
AGAIN,
ADD AX,ARRAY[SI]
ADD SI,2
LOOP AGAIN
MOV TOTAL,AX
例:在多重循环的程序结构中,CX 计数器的保存和恢复
MOV CX,M
AGAIN,……
PUSH CX
MOV CX,N
NEXT,……
LOOP NEXT
……
POP CX
LOOP AGAIN
MOV DI,M
AGAIN,……
MOV CX,N
NEXT,……
LOOP NEXT
……
DEC DI
JNZ AGAIN
子程序调用和返回指令:
code1 segment
main proc far
……
call far ptr subp
……
ret
main endp
code1 ends
code2 segment
subp proc far
……
ret
subp endp
code2 ends
段间调用和返回
code segment
main proc far
……
call subp
……
ret
main endp
subp proc near
……
ret
subp endp
code ends
段内调用和返回
CALL 调用指令段内直接近调用,CALL DST
执行操作,(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (IP)
(IP) ← (IP) + 16位位移量段内间接近调用,CALL DST
执行操作,(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (IP)
(IP) ← (EA)
段间直接远调用,CALL DST
执行操作,(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (CS)
(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (IP)
(IP) ← 偏移地址
(CS) ← 段地址段间间接远调用,CALL DST
执行操作,(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (CS)
(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (IP)
(IP) ← (EA)
(CS) ← (EA+2)
RET 返回指令段内近返回,RET
执行操作,(IP) ← ( (SP)+1,(SP) )
(SP) ← (SP) + 2
段内带立即数近返回,RET EXP
段间远返回,RET
执行操作,(IP) ← ( (SP)+1,(SP) )
(SP) ← (SP) + 2
(CS) ← ( (SP)+1,(SP) )
(SP) ← (SP) + 2
段间带立即数远返回,RET EXP
例:带立即数返回
(SP)?
堆栈段
code segment
main proc far
……
push ax
push bx
push cx
call sub
……
ret
main endp
sub proc near
……
ret 6
sub endp
code ends
(IP)
(cx)
(bx)
(ax)
(SP)?
中断指令,类型 0的 (IP)
类型 0的 (CS)
类型 1的 (IP)
类型 1的 (CS)
类型 N的 (IP)
类型 N的 (CS)
类型 255的 (IP)
类型 255的 (CS)
00000
00004
4*N
003FC
中断向量表中断向量:
中断例行程序的入口地址,
存放于中断向量区 。
00000H
003FFH
A0000H
C0000H
F0000H
640K (RAM)
128K (RAM)
192K (ROM)
64K (ROM)
中断指令,INT TYPE 或 INT
执行操作,(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (FLAGS)
(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (CS)
(SP) ← (SP) - 2
( (SP)+1,(SP) ) ← (IP)
(IP) ← (TYPE*4)
(CS) ← (TYPE*4+2)
溢出中断指令,INTO
执行操作,若 OF=1,
(IP) ← (10H)
(CS) ← (12H)
从中断返回指令,IRET
执行操作,(IP) ← ( (SP)+1,(SP) )
(SP) ← (SP) + 2
(CS) ← ( (SP)+1,(SP) )
(SP) ← (SP) + 2
(FLAGS) ← ( (SP)+1,(SP) )
(SP) ← (SP) + 2
注意:
* TYPE (0~255)是中断类型号,隐含的类型号为 3
* INT 指令还把 IF 和 TF 置 0,但不影响其它标志位
* IRET 指令执行完,标志位由堆栈中取出的值确定处理机控制与杂项操作指令:
标志处理指令
CLC,STC,CMC、
CLD,STD、
CLI,STI
其他 处理机控制与杂项操作指令
NOP,HLT,WAIT,ESC,LOCK
标志处理指令:
CLC CF ← 0
CMC CF ←?CF
STC CF ← 1
CLD DF ← 0
STD DF ← 1
CLI IF ← 0
STI IF ← 1
注意,* 只影响本指令指定的标志其他 处理机控制与杂项操作指令:
NOP 无操作 (机器码占一个字节 )
HLT 暂停机 (等待一次外中断,之后继续执行程序 )
WAIT 等待 (等待外中断,之后仍继续等待 )
ESC 换码
LOCK 封锁 (维持总线的锁存信号,直到其后的指令执行完 )
注意,* 不影响条件标志
80x86 的指令系统:
(1) 指令集的 32位扩展
* 所有 16 位指令都可扩展到 32 位
MOV EAX,1
* 可使用 32 位的存储器寻址方式
MOV EAX,[EDX]
(2) 使用方式的扩展
* IMUL:单操作数指令 → 双操作数指令 / 三操作数指令
IMUL REG,SRC
* PUSH:允许使用立即数寻址方式
PUSH 36H
* 移位指令:移位次数可用 8 位立即数 (1~31)
(3) 新增指令
MOVSX 带符号扩展传送
MOVZX 带零扩展传送
PUSHA / PUSHAD 所有寄存器进栈
POPA / POPAD 所有寄存器出栈
LFS / LGS / LSS 指针送寄存器和 FS / GS / SS
PUSHFD 标志进栈
POPFD 标志出栈
CWDE 字转换为双字 EAX
CDQ 双字转换为 4 字 EDX?EAX
BSWAP 32 位寄存器的字节次序变反
XADD 交换加
CMPXCHG 比较并交换 (486)
CMPXCHG8B 比较并交换 8 字节 (Pentium)A
BT 位测试
BTS 位测试并置 1
BTR 位测试并置 0
BTC 位测试并变反
BSF 正向位扫描
BSR 反向位扫描
SHLD 双精度左移
SHRD 双精度右移
INSB / INSW / INSD 串输入
OUTSB / OUTSW / OUTSD 串输出条件设置指令
(1) 根据单个条件标志的值把目的字节置 1
SETZ / SETE SETNZ / SETNE
SETS / SETNS SETO / SETNO
SETP / SETPE SETNP / SETPO
SETC / SETB / SETNAE SETNC / SETNB / SETAE
(2) 比较两个无符号数,根据比较结果把目的字节置 1
SETB / SETNAE / SETC SETNB / SETAE / SETNC
SETBE / SETNA SETNBE / SETA
(3) 比较两个带符号数,根据比较结果把目的字节置 1
SETL / SETNGE SETNL / SETGE
SETLE / SETNG SETNLE / SETG
其他处理机控制指令
BOUND 界限指令 ENTER 建立堆栈帧
LEAVE 释放堆栈帧特权指令第 3章 练习
Page 109
3.14 ~ 3.17
Page 107
3.23 3.26
3.30 3.31 3.34 3.36 ~ 3.38
3.39 3.22