1
逻辑指令,
? 逻辑运算指令
AND,OR,NOT,XOR,TEST
? 移位指令
SHL,SHR, SAL, SAR,ROL,ROR,RCL,RCR
2
逻辑非指令,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 * * * 无定义
根据运算结果设置
? 逻辑运算指令
3
例:屏蔽 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 * * * * *
* * * * * * * *
XOR 0 0 0 0 0 0 1 1
* * * * * * * *
* * * * * * * *
AND 1 1 1 1 1 1 0 0
* * * * * * 0 0
4
逻辑左移 SHL OPR,CNT
逻辑右移 SHR OPR,CNT
算术左移 SAL OPR,CNT( 同逻辑左移 )
算术右移 SAR OPR,CNT
CF 0
? 移位指令
0 CF
CF
5
循环左移 ROL OPR,CNT
循环右移 ROR OPR,CNT
带进位循环左移 RCL OPR,CNT
带进位循环右移 RCR OPR,CNT
CF
CF
CF
CF
6
注意,
* OPR 可用除立即数以外的任何寻址方式
* CNT = 1,SHL OPR,1
CNT > 1,MOV CL,CNT
SHL OPR,CL ; 以 SHL 为例
* 条件标志位,
CF = 移入的数值
1 CNT = 1 时,最高有效位的值发生变化
0 CNT = 1 时,最高有效位的值不变
移位指令,
SF,ZF,PF 根据移位结果设置,AF 无定义
循环移位指令,
不影响 SF,ZF,PF,AF
OF =
7
例,( AX ) = 0012H,( BX ) = 0034H,
把它们装配成 ( AX ) = 1234H
例,( BX ) = 84F0H
(1) ( BX ) 为无符号数,求 ( BX ) / 2
SHR BX,1 ; (BX) = 4278H
(2) ( BX ) 为带符号数,求 ( BX ) / 2
SAR BX,1 ; (BX) = 0C278H
MOV CL,8
ROL AX,CL
ADD AX,BX
8
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 位压入堆栈
9
串处理指令,
? 设置方向标志指令
CLD,STD
? 串处理指令 ? 串重复前缀
MOVSB / MOVSW REP
STOSB / STOSW REPE / REPZ
LODSB / LODSW REPNE / REPNZ
CMPSB / CMPSW
SCASB / SCASW
10
与 REP 配合工作的 MOVS / STOS / LODS
REP MOVS / STOS / LODS
执行操作,
(1) 如 ( CX ) = 0 则退出 REP,否则转 (2)
(2) ( CX ) ? ( CX ) - 1
(3) 执行 MOVS / STOS / LODS
(4) 重复 (1) ~ (3)
11
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,将数据段中的整串数据传送到附加段
源串 ( 数据段 ) → 目的串 ( 附加段 )
12
执行 REP MOVS 之前,应先做好,
(1) 源串首地址(末地址) → SI
(2) 目的串首地址(末地址) → DI
(3) 串长度 → CX
(4) 建立方向标志
( CLD 使 DF = 0,STD 使 DF = 1 )
13
( SI ) ? ? ( DI )
DF = 0 DF = 1
数据段 附加段
( SI ) ? ? ( DI )
14
data segment
mess1 db ‘personal_computer’
data ends
extra segment
mess2 db 17 dup (?)
extra ends
code segment
…
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
15
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
16
LODS 从串取指令,LODS SRC
LODSB ( 字节 )
LODSW ( 字 )
执行操作,
字节操作,( AL ) ← ( ( SI ) ),( SI ) ← ( SI ) ± 1
字操作,( AX ) ← ( ( SI ) ),( SI ) ← ( SI ) ± 2
注意,
* LODS 指令一般不与 REP 联用
* 源串一般在数据段中(允许使用段跨越前缀来修改),
目的串必须在附加段中
* 不影响条件标志位
17
与 REPE / REPZ ( REPNE / REPNZ ) 配合工作的 CMPS 和 SCAS
REPE / REPZ CMPS / SCAS 或
REPNE / REPNZ CMPS / SCAS
执行操作,
(1) 如 ( CX ) = 0 或 ZF = 0 ( ZF = 1 ) 则退出, 否则转 (2)
(2) ( CX ) ← ( CX ) - 1
(3) 执行 CMPS / SCAS
(4) 重复 (1) ~ (3)
18
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
19
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) ?
例:比较两个字符串,找出它们不相匹配的位置
例:反向传送 C
O
M
P
U
T
E
R
C
O
M
P
U
T
E
R
lea si,mess1
lea di,mess2
mov cx,8
cld
repe cmpsb
22
控制转移指令,
? 无条件转移指令
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
23
无条件转移指令,
段内直接短转移,JMP SHORT OPR
执行操作,( IP ) ← ( IP ) + 8 位位移量
段内直接近转移,JMP NEAR PTR OPR
执行操作,( IP ) ← ( IP ) + 16 位位移量
段内间接转移,JMP WORD PTR OPR
执行操作,( IP ) ← ( EA )
24
段间直接远转移,JMP FAR PTR OPR
执行操作,( IP ) ← OPR 的段内偏移地址
( CS ) ← OPR 所在段的段地址
段间间接转移,JMP DWORD PTR OPR
执行操作,( IP ) ← ( EA )
( CS ) ← ( EA + 2 )
25
条件转移指令,( 只能使用段内直接寻址的 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
26
(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
* 适用于地址或双精度数低位字的比较
27
(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
28
例:如果 X > 50,转到 TOO_HIGH ; 计算 X - Y,如果溢出
转到 OVERFLOW,否则 | X - Y | → RESULT
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,
……
29
例,?, ? 是双精度数, 分别存于 DX,AX 及 BX,CX 中,
? > ? 时转 L1, 否则转 L2
CMP DX,BX
JG L1
JL L2
CMP AX,CX
JA L1
L2,
……
L1,
……
30
循环指令,
注意,
* CX 中存放循环次数
* 只能使用段内直接寻址的 8 位位移量
LOOP
LOOPZ / LOOPE
LOOPNZ / LOOPNE
执行步骤,
(1) ( CX ) ← ( CX ) - 1
(2) 是否满足 测试条件,满足则 ( IP ) ← ( IP ) + 8 位位移量,
实行循环;不满足则 IP 不变, 退出循环 。
31
循环指令,LOOP OPR
测试条件,( CX ) ? 0
为零或相等时循环指令,LOOPZ ( LOOPE ) OPR
测试条件,ZF = 1 且 ( CX ) ? 0
不为零或不相等时循环指令,LOOPNZ ( LOOPNE ) OPR
测试条件,ZF = 0 且 ( CX ) ? 0
LOOP AGAIN DEC CX JNZ AGAIN
32
例:求首地址为 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
……
33
例:在多重循环的程序结构中,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
34
子程序调用和返回指令,
code1 segment
main proc far
……
call sub
……
ret
main endp
code1 ends
code2 segment
sub proc far
……
ret
sub endp
code2 ends
段间 调用和返回
code segment
main proc far
……
call sub
……
ret
main endp
sub proc near
……
ret
sub endp
code ends
段内 调用和返回
35
CALL 调用指令
段内直接近 调用,CALL DST
执行操作,( SP ) ← ( SP ) - 2
( ( SP ) + 1,( SP ) ) ← ( IP )
( IP ) ← ( IP ) + 16 位位移量
段内间接近 调用,CALL DST
执行操作,( SP ) ← ( SP ) - 2
( ( SP ) + 1,( SP ) ) ← ( IP )
( IP ) ← ( EA )
36
段间直接远 调用,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 )
37
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
38
例:带立即数返回
(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)?
39
中断指令,类型 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)
40
中断指令,INT TYPE 或 INT
执行操作,( SP ) ← ( SP ) - 2
( ( SP ) + 1,( SP ) ) ← ( PSW )
( 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 )
41
从中断返回指令,IRET
执行操作,( IP ) ← ( ( SP ) + 1,( SP ) )
( SP ) ← ( SP ) + 2
( CS ) ← ( ( SP ) + 1,( SP ) )
( SP ) ← ( SP ) + 2
( PSW ) ← ( ( SP ) + 1,( SP ) )
( SP ) ← ( SP ) + 2
注意,
* TYPE ( 0 ~ 255 ) 是中断类型号,隐含的类型号为 3
* INT 指令还把 IF 和 TF 置 0,但不影响其它标志位
* IRET 指令执行完,标志位由堆栈中取出的值确定
42
处理机控制与杂项操作指令,
? 标志处理指令
CLC,STC,CMC,
CLD,STD,
CLI,STI
? 其他 处理机控制与杂项操作指令
NOP,HLT,WAIT,ESC,LOCK
43
标志处理指令,
CLC CF ← 0
CMC CF ← ?CF
STC CF ← 1
CLD DF ← 0
STD DF ← 1
CLI IF ← 0
STI IF ← 1
注意, * 只影响本指令指定的标志
44
其他 处理机控制与杂项操作指令,
NOP 无操作 (机器码占一个字节 )
HLT 暂停机 (等待一次外中断,之后继续执行程序 )
WAIT 等待 (等待外中断,之后仍继续等待 )
ESC 换码
LOCK 封锁 (维持总线的锁存信号,直到其后的指令执行完 )
注意, * 不影响条件标志
45
80x86 的指令系统,
(1) 指令集的 32 位扩展
* 所有 16 位指令都可扩展到 32 位
MOV EAX,1
* 可使用 32 位的存储器寻址方式
MOV EAX,[ EDX ]
(2) 使用方式的扩展
* IMUL:单操作数指令 → 双操作数指令 / 三操作数指令
IMUL REG,SRC
* PUSH:允许使用立即数寻址方式
PUSH 36H
* 移位指令:移位次数可用 8 位立即数 (1~31)
46
(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 )
47
BT 位测试
BTS 位测试并置 1
BTR 位测试并置 0
BTC 位测试并变反
BSF 正向位扫描
BSR 反向位扫描
SHLD 双精度左移
SHRD 双精度右移
INSB / INSW / INSD 串输入
OUTSB / OUTSW / OUTSD 串输出
48
条件设置指令
(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 释放堆栈帧
特权指令
49
作业,
p109 3.22 3.23 3.26 3.30 3.31 3.34
3.36 3.37 3.38 3.39
逻辑指令,
? 逻辑运算指令
AND,OR,NOT,XOR,TEST
? 移位指令
SHL,SHR, SAL, SAR,ROL,ROR,RCL,RCR
2
逻辑非指令,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 * * * 无定义
根据运算结果设置
? 逻辑运算指令
3
例:屏蔽 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 * * * * *
* * * * * * * *
XOR 0 0 0 0 0 0 1 1
* * * * * * * *
* * * * * * * *
AND 1 1 1 1 1 1 0 0
* * * * * * 0 0
4
逻辑左移 SHL OPR,CNT
逻辑右移 SHR OPR,CNT
算术左移 SAL OPR,CNT( 同逻辑左移 )
算术右移 SAR OPR,CNT
CF 0
? 移位指令
0 CF
CF
5
循环左移 ROL OPR,CNT
循环右移 ROR OPR,CNT
带进位循环左移 RCL OPR,CNT
带进位循环右移 RCR OPR,CNT
CF
CF
CF
CF
6
注意,
* OPR 可用除立即数以外的任何寻址方式
* CNT = 1,SHL OPR,1
CNT > 1,MOV CL,CNT
SHL OPR,CL ; 以 SHL 为例
* 条件标志位,
CF = 移入的数值
1 CNT = 1 时,最高有效位的值发生变化
0 CNT = 1 时,最高有效位的值不变
移位指令,
SF,ZF,PF 根据移位结果设置,AF 无定义
循环移位指令,
不影响 SF,ZF,PF,AF
OF =
7
例,( AX ) = 0012H,( BX ) = 0034H,
把它们装配成 ( AX ) = 1234H
例,( BX ) = 84F0H
(1) ( BX ) 为无符号数,求 ( BX ) / 2
SHR BX,1 ; (BX) = 4278H
(2) ( BX ) 为带符号数,求 ( BX ) / 2
SAR BX,1 ; (BX) = 0C278H
MOV CL,8
ROL AX,CL
ADD AX,BX
8
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 位压入堆栈
9
串处理指令,
? 设置方向标志指令
CLD,STD
? 串处理指令 ? 串重复前缀
MOVSB / MOVSW REP
STOSB / STOSW REPE / REPZ
LODSB / LODSW REPNE / REPNZ
CMPSB / CMPSW
SCASB / SCASW
10
与 REP 配合工作的 MOVS / STOS / LODS
REP MOVS / STOS / LODS
执行操作,
(1) 如 ( CX ) = 0 则退出 REP,否则转 (2)
(2) ( CX ) ? ( CX ) - 1
(3) 执行 MOVS / STOS / LODS
(4) 重复 (1) ~ (3)
11
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,将数据段中的整串数据传送到附加段
源串 ( 数据段 ) → 目的串 ( 附加段 )
12
执行 REP MOVS 之前,应先做好,
(1) 源串首地址(末地址) → SI
(2) 目的串首地址(末地址) → DI
(3) 串长度 → CX
(4) 建立方向标志
( CLD 使 DF = 0,STD 使 DF = 1 )
13
( SI ) ? ? ( DI )
DF = 0 DF = 1
数据段 附加段
( SI ) ? ? ( DI )
14
data segment
mess1 db ‘personal_computer’
data ends
extra segment
mess2 db 17 dup (?)
extra ends
code segment
…
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
15
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
16
LODS 从串取指令,LODS SRC
LODSB ( 字节 )
LODSW ( 字 )
执行操作,
字节操作,( AL ) ← ( ( SI ) ),( SI ) ← ( SI ) ± 1
字操作,( AX ) ← ( ( SI ) ),( SI ) ← ( SI ) ± 2
注意,
* LODS 指令一般不与 REP 联用
* 源串一般在数据段中(允许使用段跨越前缀来修改),
目的串必须在附加段中
* 不影响条件标志位
17
与 REPE / REPZ ( REPNE / REPNZ ) 配合工作的 CMPS 和 SCAS
REPE / REPZ CMPS / SCAS 或
REPNE / REPNZ CMPS / SCAS
执行操作,
(1) 如 ( CX ) = 0 或 ZF = 0 ( ZF = 1 ) 则退出, 否则转 (2)
(2) ( CX ) ← ( CX ) - 1
(3) 执行 CMPS / SCAS
(4) 重复 (1) ~ (3)
18
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
19
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) ?
例:比较两个字符串,找出它们不相匹配的位置
例:反向传送 C
O
M
P
U
T
E
R
C
O
M
P
U
T
E
R
lea si,mess1
lea di,mess2
mov cx,8
cld
repe cmpsb
22
控制转移指令,
? 无条件转移指令
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
23
无条件转移指令,
段内直接短转移,JMP SHORT OPR
执行操作,( IP ) ← ( IP ) + 8 位位移量
段内直接近转移,JMP NEAR PTR OPR
执行操作,( IP ) ← ( IP ) + 16 位位移量
段内间接转移,JMP WORD PTR OPR
执行操作,( IP ) ← ( EA )
24
段间直接远转移,JMP FAR PTR OPR
执行操作,( IP ) ← OPR 的段内偏移地址
( CS ) ← OPR 所在段的段地址
段间间接转移,JMP DWORD PTR OPR
执行操作,( IP ) ← ( EA )
( CS ) ← ( EA + 2 )
25
条件转移指令,( 只能使用段内直接寻址的 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
26
(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
* 适用于地址或双精度数低位字的比较
27
(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
28
例:如果 X > 50,转到 TOO_HIGH ; 计算 X - Y,如果溢出
转到 OVERFLOW,否则 | X - Y | → RESULT
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,
……
29
例,?, ? 是双精度数, 分别存于 DX,AX 及 BX,CX 中,
? > ? 时转 L1, 否则转 L2
CMP DX,BX
JG L1
JL L2
CMP AX,CX
JA L1
L2,
……
L1,
……
30
循环指令,
注意,
* CX 中存放循环次数
* 只能使用段内直接寻址的 8 位位移量
LOOP
LOOPZ / LOOPE
LOOPNZ / LOOPNE
执行步骤,
(1) ( CX ) ← ( CX ) - 1
(2) 是否满足 测试条件,满足则 ( IP ) ← ( IP ) + 8 位位移量,
实行循环;不满足则 IP 不变, 退出循环 。
31
循环指令,LOOP OPR
测试条件,( CX ) ? 0
为零或相等时循环指令,LOOPZ ( LOOPE ) OPR
测试条件,ZF = 1 且 ( CX ) ? 0
不为零或不相等时循环指令,LOOPNZ ( LOOPNE ) OPR
测试条件,ZF = 0 且 ( CX ) ? 0
LOOP AGAIN DEC CX JNZ AGAIN
32
例:求首地址为 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
……
33
例:在多重循环的程序结构中,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
34
子程序调用和返回指令,
code1 segment
main proc far
……
call sub
……
ret
main endp
code1 ends
code2 segment
sub proc far
……
ret
sub endp
code2 ends
段间 调用和返回
code segment
main proc far
……
call sub
……
ret
main endp
sub proc near
……
ret
sub endp
code ends
段内 调用和返回
35
CALL 调用指令
段内直接近 调用,CALL DST
执行操作,( SP ) ← ( SP ) - 2
( ( SP ) + 1,( SP ) ) ← ( IP )
( IP ) ← ( IP ) + 16 位位移量
段内间接近 调用,CALL DST
执行操作,( SP ) ← ( SP ) - 2
( ( SP ) + 1,( SP ) ) ← ( IP )
( IP ) ← ( EA )
36
段间直接远 调用,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 )
37
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
38
例:带立即数返回
(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)?
39
中断指令,类型 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)
40
中断指令,INT TYPE 或 INT
执行操作,( SP ) ← ( SP ) - 2
( ( SP ) + 1,( SP ) ) ← ( PSW )
( 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 )
41
从中断返回指令,IRET
执行操作,( IP ) ← ( ( SP ) + 1,( SP ) )
( SP ) ← ( SP ) + 2
( CS ) ← ( ( SP ) + 1,( SP ) )
( SP ) ← ( SP ) + 2
( PSW ) ← ( ( SP ) + 1,( SP ) )
( SP ) ← ( SP ) + 2
注意,
* TYPE ( 0 ~ 255 ) 是中断类型号,隐含的类型号为 3
* INT 指令还把 IF 和 TF 置 0,但不影响其它标志位
* IRET 指令执行完,标志位由堆栈中取出的值确定
42
处理机控制与杂项操作指令,
? 标志处理指令
CLC,STC,CMC,
CLD,STD,
CLI,STI
? 其他 处理机控制与杂项操作指令
NOP,HLT,WAIT,ESC,LOCK
43
标志处理指令,
CLC CF ← 0
CMC CF ← ?CF
STC CF ← 1
CLD DF ← 0
STD DF ← 1
CLI IF ← 0
STI IF ← 1
注意, * 只影响本指令指定的标志
44
其他 处理机控制与杂项操作指令,
NOP 无操作 (机器码占一个字节 )
HLT 暂停机 (等待一次外中断,之后继续执行程序 )
WAIT 等待 (等待外中断,之后仍继续等待 )
ESC 换码
LOCK 封锁 (维持总线的锁存信号,直到其后的指令执行完 )
注意, * 不影响条件标志
45
80x86 的指令系统,
(1) 指令集的 32 位扩展
* 所有 16 位指令都可扩展到 32 位
MOV EAX,1
* 可使用 32 位的存储器寻址方式
MOV EAX,[ EDX ]
(2) 使用方式的扩展
* IMUL:单操作数指令 → 双操作数指令 / 三操作数指令
IMUL REG,SRC
* PUSH:允许使用立即数寻址方式
PUSH 36H
* 移位指令:移位次数可用 8 位立即数 (1~31)
46
(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 )
47
BT 位测试
BTS 位测试并置 1
BTR 位测试并置 0
BTC 位测试并变反
BSF 正向位扫描
BSR 反向位扫描
SHLD 双精度左移
SHRD 双精度右移
INSB / INSW / INSD 串输入
OUTSB / OUTSW / OUTSD 串输出
48
条件设置指令
(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 释放堆栈帧
特权指令
49
作业,
p109 3.22 3.23 3.26 3.30 3.31 3.34
3.36 3.37 3.38 3.39