第2章 IA-32处理器基本功能
2.2 通用寄存器及使用
2.3 标志寄存器及使用
2.4 段寄存器
2.5 寻址方式
2.6 指令指针寄存器和简单控制转移
2.7 堆栈和堆栈操作
2.1 IA-32处理器简介
2.1.1 IA-32系列处理器
2.1.2 保护方式和实地址方式
2.1.1 IA-32系列处理器
32
位微处理器
保持与先前处理器的兼容
.泛指:基于英特尔IA-32架构的32位微处理器
Intel 80386/80486
Intel Pentium(奔腾)
Intel Xeon(至强)
Intel Core(酷睿)
. 最大特点:保持与先前处理器的兼容
.IA-32系列处理器
2.1.1 IA-32系列处理器
.处理数据的位数
.16位
.32位
.64位
.主频
.平行化程度
.流水线
.多核
.处理器的重要指标
2.1.1 IA-32系列处理器
.1978年,Intel率先推出16位微处理器8086
.1979年,Intel推出准16位微处理器8088
.1982年,Intel推出“超级”16位微处理器80286
.早期的16位处理器
2.1.1 IA-32系列处理器
.
全面支持
32
位数据类型和
32
位操作
.
为进入
32
位时代做好了充分准备
.1985年,Intel推出32位微处理器80386
.全面支持32位数据类型和32位操作
.支持实地址方式和保护方式两种工作方式
.保护方式下,可寻址的物理地址空间高达4G
.保护方式下,提供了完善的保护机制
.为进入32位时代做好了充分准备
.第一款32位处理器
2.1.1 IA-32系列处理器
.1989年,推出80486
.1993年,推出Pentium(奔腾)
.1995年,推出Pentium Pro(高能奔腾)
.2000年,Pentium 4系列处理器面世
.2001年,Xeon(至强)处理器系列被推出
.2003年,Pentium M处理器被推出
.最近几年,新的功能更强的处理器不断被推出
.不断推陈出新
从普通程序员角度去看,这些处理器并没有显著差异
2.1.2 保护方式和实地址方式
.
只有在保护方式下,
IA
-
32
系列处理器才能够发挥出其全
部性能和特点
.现在保护方式(Protected mode)是IA-32系列处理器的常态
工作方式
.只有在保护方式下,IA-32系列处理器才能够发挥出其全
部性能和特点
.Windows操作系统和基于IA-32处理器的Linux操作系统都运
行于保护方式
.保护方式
保护
2.1.2 保护方式和实地址方式
可寻址高达
4G
字节的物理地址空间
虚拟
8086
方式
.全部32根地址线有效,可寻址高达4G字节的物理地址空间
.支持存储器分段管理和可选的存储器分页管理机制
.支持虚拟存储器的实现
.提供完善的保护机制
.支持操作系统实现多任务管理
.支持虚拟8086方式(Virtual-8086 mode)
.保护方式
2.1.2 保护方式和实地址方式
.
实地址方式是处理器重新开始运行后的最初工作方式
.
实地址方式是
IA
-
32
系列处理器中最初的处理器的工作方
式
.实地址方式(Real-address mode)是最初的工作方式
.实地址方式是处理器重新开始运行后的最初工作方式。
.实地址方式是IA-32系列处理器中最初的处理器的工作方
式。很久以前的 8086/8088处理器只具有所谓的实地址方
式,没有保护方式。
.实地址方式
2.1.2 保护方式和实地址方式
实方式
.只能访问最低端的1M字节的物理地址空间。地址空间的
范围是00000H至FFFFFH
.只支持存储器的分段管理,而且每个存储段的大小限于
64K字节
.实地址对应保护方式下的虚地址。这应该是实地址方式
的名称由来。实地址方式常常被简称为实方式
.在实方式下,IA-32系列处理器不能发挥其全部性能
.实地址方式
2.1.2 保护方式和实地址方式
.工作方式的切换
实地址方式
保护方式
虚拟8086方式
系统管理方式
ResetRSMRSMRSMSMI#
SMI#
SMI#
PE=1PE=0VM=1VM=0
2.2 通用寄存器及使用
2.2.1 通用寄存器
2.2.2 简单传送指令
2.2.3 简单加减指令
2.2.4 VC嵌入汇编和实验
2.2.1 通用寄存器
.处理器内的特殊存储单元
.处理器内有多种不同用途的寄存器
.寄存器分别有各自的名称,以便表示及访问
.寄存器
2.2.1 通用寄存器
8
个
32
位的
通用寄存器
EAX
、
EBX
、
ECX
、
EDX
、
ESI
、
EDI
、
EBP
、
ESP
.IA-32系列CPU有8个32位的通用寄存器(General-Purpose
Registers)
.通用寄存器不仅能存储数据,而且能参与算术逻辑运算,
还能给出存储单元的地址
.名称分别是:
EAX、EBX、ECX、EDX、ESI、EDI、EBP、ESP
.通用寄存器
2.2.1 通用寄存器
.通用寄存器
EAX
EAX
EBX
EBX
EBP
EBP
ESI
ESI
EDI
EDI
ECX
ECX
EDX
EDX
ESP
ESP
0
0 31
31
2.2.1 通用寄存器
.通用寄存器
MOV EAX, 12345678H ;EAX=12345678H
MOV ESI, 11223344H ;ESI=11223344H
ADD EAX, ESI ;EAX=235689BCH
MOV EBX, EAX ;EBX=235689BCH
MOV ECX, [ESI] ;ESI
作为指针给出存储单元地址
MOV EDX, [EBX+8] ;EBX
作为计算存储单元地址的一部分
MOV EAX, 12345678H ;EAX=12345678H
MOV ESI, 11223344H ;ESI=11223344H
ADD EAX, ESI ;EAX=235689BCH
MOV EBX, EAX ;EBX=235689BCH
MOV ECX, [ESI] ;ESI作为指针给出存储单元地址
MOV EDX, [EBX+8] ;EBX作为计算存储单元地址的一部分
2.2.1 通用寄存器
.通用寄存器
单独直接访问这些通用寄存器的低
16
位
AX
、
BX
、
CX
、
DX
、
SI
、
DI
、
BP
、
SP
.可以单独直接访问这些通用寄存器的低16位
.它们是8个16位的通用寄存器
.名称分别是 AX、BX、CX、DX、SI、DI、BP、SP
.对应16位处理器Intel 8086的8个通用寄存器
EAX
EAX
EBX
EBX
EBP
EBP
ESI
ESI
EDI
EDI
ECX
ECX
EDX
EDX
ESP
ESP
0 31
31
AX
AX
BX
BX
CX
CX
DX
DX
SI
SI
DI
DI
BP
BP
SP
SP
15
15
16
16 0
0
2.2.1 通用寄存器
.通用寄存器
.
可单独直接访问
AX
、
BX
、
CX
和
DX
的高
8
位和低
8
位
AH
、
AL
、
BH
、
BL
、
CH
、
CL
、
DH
、
DL
.可单独直接访问AX、BX、CX和DX的高8位和低8位
.它们是8个8位的通用寄存器
.名称分别是 AH、AL、BH、BL、CH、CL、DH、DL
EAX
EAX
EBX
EBX
EBP
EBP
ESI
ESI
EDI
EDI
ECX
ECX
EDX
EDX
ESP
ESP
0
0 31
31
AH
AH
BH
BH
CH
CH
DH
DH
SI
SI
DI
DI
BP
BP
SP
SP
15
15
16
16
AL
AL
BL
BL
CL
CL
DL
DL
AX
AX
BX
BX
CX
CX
DX
DX
7
7 8
8
有名称的通用寄存器,
可以独立访问;
否则,不行
有名称的通用寄存器,
可以独立访问;
否则,不行
2.2.1 通用寄存器
.通用寄存器
.32位通用寄存器的名称是在对应16位寄存器名称前加字母E
.AH是AX的高(High)字节;AL是AX的低(Low)字节
.EAX是AX的扩展
AH
AH
AL
AL
AX
AX
EAX
EAX
0
0
7
7 8
8 15
15 16
16
31
31
2.2.1 通用寄存器
.通用寄存器
MOV EAX, 11112222H ;EAX=11112222H
MOV AX, 9999H ;EAX=
1111
9999
H
MOV EDX, EAX ;EDX=11119999H
MOV DX, 8765H ;EDX=
1111
8765
H
ADD AX, DX ;EAX=
1111
20FE
H
MOV EAX, 11112222H ;EAX=11112222H
MOV AX, 9999H ;EAX=11119999H
MOV EDX, EAX ;EDX=11119999H
MOV DX, 8765H ;EDX=11118765H
ADD AX, DX ;EAX=111120FEH
对32位寄存器低16位独立操作,
不影响高16位
2.2.1 通用寄存器
.通用寄存器
MOV EBX, 11112222H ;EBX=11112222H
MOV BH, 77H ;EBX=1111
77
22
H
MOV BL, 99H ;EBX=1111
77
99
H
ADD BL, 82H ;EBX=1111
77
1B
H
MOV EBX, 11112222H ;EBX=11112222H
MOV BH, 77H ;EBX=11117722H
MOV BL, 99H ;EBX=11117799H
ADD BL, 82H ;EBX=1111771BH
对16位寄存器的8位独立操作,
不影响另外8位
2.2.2 简单传送指令
.传送指令MOV
.交换指令XCHG
2.2.2 简单传送指令
.MOV指令的一般格式
MOV DST,SRC
.MOV指令的动作
DST ← SRC
.把一个字节、一个字或者一个双字,
从源SRC送到目标DST。
.传送指令(MOV)
这是在程序中用得最多的指令。注意:
源和目标的尺寸必须一致;
不能同时是存储单元!
这是在程序中用得最多的指令。注意:
源和目标的尺寸必须一致;
不能同时是存储单元!
2.2.2 简单传送指令
.使用举例
MOV
EAX, 12345678H
MOV
EBX, EAX
MOV
ESI, 256
MOV
ECX,
-
1
MOV
BX, ‘b’
MOV
AH, AL
MOV
CX, AX
MOV
AX, SI
MOV
SI, BX
MOV
AL, BH
MOV EAX, 12345678H
MOV EBX, EAX
MOV ESI, 256
MOV ECX, -1
MOV BX, ‘b’
MOV AH, AL
MOV CX, AX
MOV AX, SI
MOV SI, BX
MOV AL, BH
EAX =
12345678
H
EBX =
12345678
H
ESI =
00000100
H
ECX =
FFFFFFFF
H
EBX =
1234
0062
H
EAX =
1234
78
78H
ECX =
FFFF
7878
H
EAX =
1234
0100
H
ESI =
0000
0062
H
EAX =
123401
00
H
EAX = 12345678H
EBX = 12345678H
ESI = 00000100H
ECX = FFFFFFFFH
EBX = 12340062H
EAX = 12347878H
ECX = FFFF7878H
EAX = 12340100H
ESI = 00000062H
EAX = 12340100H
.传送指令(MOV)
2.2.2 简单传送指令
.XCHG指令的一般格式
XCHG OPRD1,OPRD2
.XCHG指令的动作
OPRD1 ←→ OPRD2
.操作数OPRD1的内容与操作数OPRD2的内容交换。
.交换指令(XCHG)
源和目标的尺寸必须一致。
不能同时是存储单元。
源和目标的尺寸必须一致。
不能同时是存储单元。
2.2.2 简单传送指令
.使用举例
XCHG AL,
AH ;
8
位交换
XCHG SI, BX ;16
位交换
XCHG EAX, EBX ;32
位交换
XCHG AL, [EBX] ;AL
与由
EBX
指定的
字节
存储单元交换
XCHG [ESI], BX ;BX
与由
ESI
指定的
字
存储单元交换
XCHG EDX, [EDI] ;EDX
与由
EDI
指定的
双字
存储单元交换
XCHG AL, AH ;8位交换
XCHG SI, BX ;16位交换
XCHG EAX, EBX ;32位交换
XCHG AL, [EBX] ;AL与由EBX指定的字节存储单元交换
XCHG [ESI], BX ;BX与由ESI指定的字存储单元交换
XCHG EDX, [EDI] ;EDX与由EDI指定的双字存储单元交换
.交换指令(XCHG)
2.2.3 简单加减指令
.加法指令ADD
.减法指令SUB
.加1指令INC
.减1指令DEC
.取补指令NEG
2.2.3 简单加减指令
.ADD指令的一般格式
ADD DST,SRC
.ADD指令的动作
DST ← DST + SRC
.把目标DST和源SRC相加,结果送到目标DST。
.加法指令(ADD)
这是在程序中运用得很普遍的指令。
实现
8
位相加、
16
位相加或者
32
位相加。
注意:
源和目标的尺寸必须一致。
这是在程序中运用得很普遍的指令。
实现8位相加、16位相加或者32位相加。
注意:源和目标的尺寸必须一致。
2.2.3 简单加减指令
.使用举例
MOV
EAX, 12345678H
MOV
ECX, 01010101H
ADD
EAX, ECX
ADD
CX, AX
ADD
AL, CH
ADD
AL, 3
ADD
CX, 2000H
MOV EAX, 12345678H
MOV ECX, 01010101H
ADD EAX, ECX
ADD CX, AX
ADD AL, CH
ADD AL, 3
ADD CX, 2000H
EAX =
12345678
H
ECX =
01010101
H
EAX =
13355779
H
ECX =
0101
587A
H
EAX =
133557
D1
H
EAX =
133557
D4
H
ECX =
0101
787A
H
EAX = 12345678H
ECX = 01010101H
EAX = 13355779H
ECX = 0101587AH
EAX = 133557D1H
EAX = 133557D4H
ECX = 0101787AH
.加法指令(ADD)
2.2.3 简单加减指令
.使用举例
MOV
EAX, 00001298H
ADD
AL, 81H
MOV EAX, 00001298H
ADD AL, 81H
EAX =
00001298
(十六进制)
EAX =
000012
19
EAX = 00001298 (十六进制)
EAX = 00001219
MOV
EAX, 00001298H
ADD
AX, 81H
MOV EAX, 00001298H
ADD AX, 81H
EAX =
00001298
(十六进制)
EAX =
0000
1319
EAX = 00001298 (十六进制)
EAX = 00001319
MOV
EAX, 00009876H
MOV
EBX, 00008765H
ADD
BX, AX
MOV EAX, 00009876H
MOV EBX, 00008765H
ADD BX, AX
MOV
EAX, 00009876H
MOV
EBX, 00008756H
ADD
EAX, EBX
MOV EAX, 00009876H
MOV EBX, 00008756H
ADD EAX, EBX
EAX =
00009876
(十六进制)
EBX =
00008765
EBX =
0000
1FDB
EAX = 00009876 (十六进制)
EBX = 00008765
EBX = 00001FDB
EAX =
00009876
(十六进制)
EBX =
00008765
EBX =
00011FDB
EAX = 00009876 (十六进制)
EBX = 00008765
EBX = 00011FDB
.加法指令(ADD)
8位或16位
独立操作!
2.2.3 简单加减指令
.SUB指令的一般格式
SUB DST,SRC
.SUB指令的动作
DST ← DST - SRC
.把目标DST减去源SRC,结果送到目标DST。
.减法指令(SUB)
实现
8
位相减、
16
位相减或
32
位相减。
注意:
源和目标的尺寸必须一致
。
实现8位相减、16位相减或32位相减。
注意:源和目标的尺寸必须一致。
2.2.3 简单加减指令
SUB EDX, 1000 ;
使
EDX
减去
1000
SUB ESI, EBX ;
使
ESI
减去
EBX
值
SUB DI, 20 ;
使
DI
减去
20
SUB DH, CL ;
使
DH
减去
CL
值
SUB AL, 7 ;
使
AL
减去
7
SUB ECX, [EDI] ;
使
ECX
减去由
EDI
指定的双字存储单元值
SUB EDX, 1000 ;使EDX减去1000
SUB ESI, EBX ;使ESI减去EBX值
SUB DI, 20 ;使DI减去20
SUB DH, CL ;使DH减去CL值
SUB AL, 7 ;使AL减去7
SUB ECX, [EDI] ;使ECX减去由EDI指定的双字存储单元值
.使用举例
.减法指令(SUB)
2.2.3 简单加减指令
.INC指令的一般格式
INC DST
.INC指令的动作
DST ← DST + 1
.对操作数DST加1,然后把结果送回DST。
.加1指令(INC)
操作数
DST
可以是通用寄存器,也可以是存储单元。
操作数
DST
可以是
8
位、
16
位或
32
位。
操作数DST可以是通用寄存器,也可以是存储单元。
操作数DST可以是8位、16位或32位。
2.2.3 简单加减指令
INC ESI ;
使寄存器
ESI
值加
1
INC DI ;
使寄存器
DI
值加
1
INC CL ;
使寄存器
CL
值加
1
INC ESI ;使寄存器ESI值加1
INC DI ;使寄存器DI值加1
INC CL ;使寄存器CL值加1
.使用举例
.加1指令(INC)
2.2.3 简单加减指令
.DEC指令的一般格式
DEC DST
.DEC指令的动作
DST ← DST - 1
.对操作数DST减1,然后把结果送回DST。
.减1指令(DEC)
操作数
DST
可以是通用寄存器,也可以是存储单元。
操作数
DST
可以是
8
位、
16
位或
32
位。
操作数DST可以是通用寄存器,也可以是存储单元。
操作数DST可以是8位、16位或32位。
2.2.3 简单加减指令
DEC EDI ;
使寄存器
EDI
值减
1
DEC SI ;
使寄存器
SI
值减
1
DEC AL ;
使寄存器
AL
值减
1
DEC EDI ;使寄存器EDI值减1
DEC SI ;使寄存器SI值减1
DEC AL ;使寄存器AL值减1
.使用举例
.减1指令(DEC)
2.2.3 简单加减指令
.NEG指令的一般格式
NEG OPRD
.NEG指令的动作
OPRD ← 0 - OPRD
.取得操作数的负数,结果送回OPRD。
.操作数是以补码表示的。
.取补指令(NEG)
操作数
OPRD
可以是通用寄存器,也可以是存储单元。
操作数OPRD可以是通用寄存器,也可以是存储单元。
2.2.3 简单加减指令
MOV AL, 3 ;AL=03H
NEG AL ;AL=
FD
H
(
-
3
)
MOV EDX,
-
5 ;EAX=FFFFFFFBH
NEG EDX ;EAX=
00000005
H
MOV AL, 3 ;AL=03H
NEG AL ;AL=FDH(-3)
MOV EDX, -5 ;EAX=FFFFFFFBH
NEG EDX ;EAX=00000005H
.使用举例
.取补指令(NEG)
2.3 标志寄存器及使用
2.3.1 标志寄存器
2.3.2 状态标志
2.3.3 状态标志操作指令
2.3.4 带进位加减指令
2.3.1 标志寄存器
.标志寄存器(EFLAGS register)
反映处理器的状态和运算结果的某些
特征
状态
标志
控制
标志
.一个32位的寄存器
.用于反映处理器的状态和运算结果的某些特征
.可以暂时认为主要是,状态标志和控制标志
.低端16位对应8086的FLAGS寄存器
FLAGS
0
15 16
31
31302928272625242322X21X20X19X18X17X1615X14X1312OF11Y10X9X8SF7ZF65AF43PF21CF0
2.3.1 标志寄存器
.一组状态标志
.一组系统标志
.一个控制标志
CFPFAFZFSFOFDFIFTF0131114121598107645321
.标志寄存器的低16位(FLAGS register)
2.3.2 状态标志
CFPFAFZFSFOFDFIFTF0131114121598107645321
.CF:进位标志(Carry Flag)
.ZF:零标志(Zero Flag)
.SF:符号标志(Sign Flag)
.OF:溢出标志(Overflow Flag)
.PF:奇偶标志(Parity Flag)
.AF:辅助进位标志(Auxiliary Carry Flag)
.状态标志
2.3.2 状态标志
.CF:进位标志(Carry Flag)
.当算术运算产生进位或者借位时,置标志;否则清标志。
.作为无符号数运算产生溢出的条件。
MOV
EAX, 77009966H
MOV
EDX, 55440000H
ADD
EAX, EDX
ADD
EDX, EAX
ADD
AX, AX
ADD
AL, 6
ADD
AL, 52H
ADD
AX, 0CDDCH
ADD
EAX, 33BC0000H
MOV EAX, 77009966H
MOV EDX, 55440000H
ADD EAX, EDX
ADD EDX, EAX
ADD AX, AX
ADD AL, 6
ADD AL, 52H
ADD AX, 0CDDCH
ADD EAX, 33BC0000H
EAX =
77009966
(十六进制)
EDX =
55440000
EAX =
CC449966
CF=
0
EDX =
21889966
CF=
1
EAX =
CC44
32CC
CF=
1
EAX =
CC4432
D2
CF=
0
EAX =
CC4432
24
CF=
1
EAX =
CC44
0000
CF=
1
EAX =
00000000
CF=
1
EAX = 77009966 (十六进制)
EDX = 55440000
EAX = CC449966 CF=0
EDX = 21889966 CF=1
EAX = CC4432CC CF=1
EAX = CC4432D2 CF=0
EAX = CC443224 CF=1
EAX = CC440000 CF=1
EAX = 00000000 CF=1
2.3.2 状态标志
.ZF:零标志(Zero Flag)
.当运算结果为0时,置标志;否则清标志。
MOV
EAX, 77009966H
MOV
EDX, 55440000H
ADD
EAX, EDX
ADD
EDX, EAX
ADD
AX, AX
ADD
AL, 6
ADD
AL, 52H
ADD
AX, 0CDDCH
ADD
EAX, 33BC0000H
MOV EAX, 77009966H
MOV EDX, 55440000H
ADD EAX, EDX
ADD EDX, EAX
ADD AX, AX
ADD AL, 6
ADD AL, 52H
ADD AX, 0CDDCH
ADD EAX, 33BC0000H
EAX =
77009966
(十六进制)
EDX =
55440000
EAX =
CC449966
ZF=
0
EDX =
21889966
ZF=
0
EAX =
CC44
32CC
ZF=
0
EAX =
CC4432
D2
ZF=
0
EAX =
CC4432
24
ZF=
0
EAX =
CC44
0000
ZF=
1
EAX =
00000000
ZF=
1
EAX = 77009966 (十六进制)
EDX = 55440000
EAX = CC449966 ZF=0
EDX = 21889966 ZF=0
EAX = CC4432CC ZF=0
EAX = CC4432D2 ZF=0
EAX = CC443224 ZF=0
EAX = CC440000 ZF=1
EAX = 00000000 ZF=1
2.3.2 状态标志
.SF:符号标志(Sign Flag)
.反映运算结果的符号位;(符号位为1,置标志;否则清)
.与运算结果的最高位相同。
MOV
EAX, 77009966H
MOV
EDX, 55440000H
ADD
EAX, EDX
ADD
EDX, EAX
ADD
AX, AX
ADD
AL, 6
ADD
AL, 52H
ADD
AX, 0CDDCH
ADD
EAX, 33BC0000H
MOV EAX, 77009966H
MOV EDX, 55440000H
ADD EAX, EDX
ADD EDX, EAX
ADD AX, AX
ADD AL, 6
ADD AL, 52H
ADD AX, 0CDDCH
ADD EAX, 33BC0000H
EAX =
77009966
(十六进制)
EDX =
55440000
EAX =
CC449966
SF=
1
EDX =
21889966
SF=
0
EAX =
CC44
32CC
SF=
0
EAX =
CC4432
D2
SF=
1
EAX =
CC4432
24
SF=
0
EAX =
CC44
0000
SF=
0
EAX =
00000000
SF=
0
EAX = 77009966 (十六进制)
EDX = 55440000
EAX = CC449966 SF=1
EDX = 21889966 SF=0
EAX = CC4432CC SF=0
EAX = CC4432D2 SF=1
EAX = CC443224 SF=0
EAX = CC440000 SF=0
EAX = 00000000 SF=0
2.3.2 状态标志
.OF:溢出标志(Overflow Flag)
.反映有符号数的加减运算是否引起溢出;
.如果溢出,置标志;否则清标志。
MOV
EAX, 77009966H
MOV
EDX, 55440000H
ADD
EAX, EDX
ADD
EDX, EAX
ADD
AX, AX
ADD
AL, 6
ADD
AL, 52H
ADD
AX, 0CDDCH
ADD
EAX, 33BC0000H
MOV EAX, 77009966H
MOV EDX, 55440000H
ADD EAX, EDX
ADD EDX, EAX
ADD AX, AX
ADD AL, 6
ADD AL, 52H
ADD AX, 0CDDCH
ADD EAX, 33BC0000H
EAX =
77009966
(十六进制)
EDX =
55440000
EAX =
CC449966
OF=
1
EDX =
21889966
OF=
0
EAX =
CC44
32CC
OF=
1
EAX =
CC4432
D2
OF=
0
EAX =
CC4432
24
OF=
0
EAX =
CC44
0000
OF=
0
EAX =
00000000
OF=
0
EAX = 77009966 (十六进制)
EDX = 55440000
EAX = CC449966 OF=1
EDX = 21889966 OF=0
EAX = CC4432CC OF=1
EAX = CC4432D2 OF=0
EAX = CC443224 OF=0
EAX = CC440000 OF=0
EAX = 00000000 OF=0
2.3.3 状态标志操作指令
.进位标志操作指令
CLC ; 清CF
STC ; 置CF
CMC ; CF取反
.使用举例
MOV
AX, 8899H
ADD
AL, AH
CLC
STC
CMC
CMC
MOV AX, 8899H
ADD AL, AH
CLC
STC
CMC
CMC
AX =
8899H
AX = 88
21H CF=1
CF=0
CF=1
CF=0
CF=1
AX = 8899H
AX = 88 21H CF=1
CF=0
CF=1
CF=0
CF=1
2.3.3 状态标志操作指令
.获取状态标志操作指令(LAHF)
LAHF
.把标志寄存器的低8位,送到通用寄存器AH中
2.3.3 状态标志操作指令
.设置状态标志操作指令(SAHF)
SAHF
.使得状态标志SF、ZF、AF、PF和CF分别成为来自寄
存器AH中对应位的值
2.3.3 状态标志操作指令
.演示程序dp25
#include <
stdio.h
>
int
main( )
{ //
定义
3
个无符号字节变量
unsigned char flag1, flag2, flag3;
//
嵌入汇编
_
asm
{
.. .. ..
}
printf
("flag1=%02XH
\
n", flag1); //
显示为
flag1=02H
printf
("flag2=%02XH
\
n", flag2); //
显示为
flag1=13H
printf
("flag3=%02XH
\
n", flag3); //
显示为
flag1=86H
return 0;
}
#include <stdio.h>
int main( )
{ //定义3个无符号字节变量
unsigned char flag1, flag2, flag3;
//嵌入汇编
_asm {
.. .. ..
}
printf("flag1=%02XH\n", flag1); //显示为flag1=02H
printf("flag2=%02XH\n", flag2); //显示为flag1=13H
printf("flag3=%02XH\n", flag3); //显示为flag1=86H
return 0;
}
2.3.3 状态标志操作指令
.演示程序dp25
_
asm
{
MOV AH, 0
SAHF //SF=0
,
ZF=0
,
PF=0
,
AF=0
,
CF=0
LAHF //
把标志寄存器低
8
位
(02H)
又回送到
AH
MOV flag1, AH //
把
AH
的值保存到变量
flag1
;
MOV DX, 7799H //DX=7799H
ADD DL, DH //DX=7710H
,
AF=1
,
CF=1
LAHF //
把标志寄存器低
8
位
(13H)
送到
AH
寄存器
MOV flag2, AH //
把
AH
的值保存到变量
flag2
;
SUB DH, 84H //DH=F310H
,
SF=1
,
CF=1
CLC //CF=0
LAHF //
把标志寄存器低
8
位
(86H)
送到
AH
MOV flag3, AH //
把
AH
的值保存到变量
flag3
}
_asm {
MOV AH, 0
SAHF //SF=0,ZF=0,PF=0,AF=0,CF=0
LAHF //把标志寄存器低8位(02H)又回送到AH
MOV flag1, AH //把AH的值保存到变量flag1
;
MOV DX, 7799H //DX=7799H
ADD DL, DH //DX=7710H,AF=1,CF=1
LAHF //把标志寄存器低8位(13H)送到AH寄存器
MOV flag2, AH //把AH的值保存到变量flag2
;
SUB DH, 84H //DH=F310H,SF=1,CF=1
CLC //CF=0
LAHF //把标志寄存器低8位(86H)送到AH
MOV flag3, AH //把AH的值保存到变量flag3
}
2.3.4 带进位加减指令
.带进位加法指令ADC
.带借位减法指令SBB
2.3.4 带进位加减指令
.ADC指令的一般格式(ADD with Carry)
ADC DST,SRC
.ADC指令的动作
DST ← DST + SRC+ CF
.把目标DST、源SRC和进位标志CF相加,
结果送到目标DST。
.带进位加指令(ADC)
该指令实现带进位的加操作。
注意:
源和目标的尺寸必须一致
。
该指令实现带进位的加操作。
注意:源和目标的尺寸必须一致。
2.3.4 带进位加减指令
.使用举例
SUB EAX, EAX
;
EAX=0, CF=0
AD
C
EAX, 2
;
EAX=2, CF=0
STC
;
CF=1
AD
C
EAX, 2
;
EAX=5, CF=0
SUB EAX, EAX ;EAX=0, CF=0
ADC EAX, 2 ;EAX=2, CF=0
STC ;CF=1
ADC EAX, 2 ;EAX=5, CF=0
.带进位加指令(ADC)
2.3.4 带进位加减指令
.演示程序dp26
#include <
stdio.h
>
int
main( )
{
unsigned char vch1=188,vch2=172,vch3=233;//
定义
3
个字节变量
unsigned
int
sum=0; //
无符号整型变量
//
嵌入汇编
_
asm
{
.. .. ..
}
printf
("sum=%u
\
n", sum); //
显示为
sum=593
return 0;
}
#include <stdio.h>
int main( )
{
unsigned char vch1=188,vch2=172,vch3=233;//定义3个字节变量
unsigned int sum=0; //无符号整型变量
//嵌入汇编
_asm {
.. .. ..
}
printf("sum=%u\n", sum); //显示为sum=593
return 0;
}
2.3.4 带进位加减指令
.演示程序dp26
_
asm
{
SUB EDX, EDX //
使
EDX
为
0
,用
DX
存放累加和
ADD DL, vch1 //
加第
1
个字节
ADC DH, 0 //
高
8
位相加(保持形式一致)
ADD DL, vch2 //
加第
2
个字节
ADC DH, 0 //
高
8
位相加(考虑可能出现的进位)
ADD DL, vch3 //
加第
3
个字节
ADC DH, 0 //
高
8
位相加(考虑可能出现的进位)
MOV sum, EDX //
把结果送到变量
sum
}
_asm {
SUB EDX, EDX //使EDX为0,用DX存放累加和
ADD DL, vch1 //加第1个字节
ADC DH, 0 //高8位相加(保持形式一致)
ADD DL, vch2 //加第2个字节
ADC DH, 0 //高8位相加(考虑可能出现的进位)
ADD DL, vch3 //加第3个字节
ADC DH, 0 //高8位相加(考虑可能出现的进位)
MOV sum, EDX //把结果送到变量sum
} 00xxDHDL
某字节vchiCF
寄存器DX
2.3.4 带进位加减指令
.SBB指令的一般格式( Integer Subtraction with borrow )
SBB DST,SRC
.SBB指令的动作
DST ← DST – (SRC+ CF)
.把目标DST减去源SRC和借位标志CF,结果送到目标DST。
.带借位减指令(SBB)
该指令实现带借位减操作。
注意:
源和目标的尺寸必须一致
。
该指令实现带借位减操作。
注意:源和目标的尺寸必须一致。
2.3.4 带进位加减指令
.使用举例
MOV AX, 620H
;
AX=0620H
SUB AL, 21H
;
AL=FFH, CF=1, AX=06FFH
SBB AH, 2
;
AH=03H, CF=0, AX=03FFH
SBB AH, 2
;
AH=01H, CF=0
MOV AX, 620H ;AX=0620H
SUB AL, 21H ;AL=FFH, CF=1, AX=06FFH
SBB AH, 2 ;AH=03H, CF=0, AX=03FFH
SBB AH, 2 ;AH=01H, CF=0
.带借位减指令(SBB)
*指令对标志位的影响
.指令对标志的影响情况,根据每条指令的功能而定。
.算术运算指令根据运算结果,影响6个状态标志。
MOV
EAX, 12345678H
MOV
EDX, 20000000H
SUB
EAX, EDX
ADC
DL, 0
ADD
AL, AH
STC
MOV EAX, 12345678H
MOV EDX, 20000000H
SUB EAX, EDX
ADC DL, 0
ADD AL, AH
STC
EAX
=
12345678
(十六进制)
EDX
= 20000000
EAX
= F2345678
CF=1
,
ZF=0
,
SF=1
,
OF=0
,
PF=1
,
AF=0
EDX
= 20000001
CF=0
,
ZF=0
,
SF=0
,
OF=0
,
PF=0
,
AF=0
EAX
= F23456CE
CF=0
,
ZF=0
,
SF=1
,
OF=1
,
PF=0
,
AF=0
CF = 1
EAX = 12345678 (十六进制)
EDX = 20000000
EAX = F2345678
CF=1,ZF=0,SF=1,OF=0,PF=1,AF=0
EDX = 20000001
CF=0,ZF=0,SF=0,OF=0,PF=0,AF=0
EAX = F23456CE
CF=0,ZF=0,SF=1,OF=1,PF=0,AF=0
CF = 1
*指令对标志位的影响
SBB
EAX, EDX
ADC
AX, 39H
SBB
DH, DL
SUB
DL, DL
SBB EAX, EDX
ADC AX, 39H
SBB DH, DL
SUB DL, DL
EAX
=
F23456CE
(十六进制)
EDX
= 20000001 CF=1
EAX
= D23456CC
CF=0
,
ZF=0
,
SF=1
,
OF=0
,
PF=1
,
AF=0
EAX =
D2345705
CF =0
,
ZF=0
,
SF=0
,
OF=0
,
PF=1
,
AF=1
EDX =
2000FF01
CF=1
,
ZF=0
,
SF=1
,
OF=0
,
PF=1
,
AF=1
EDX =
2000FF00
CF=0
,
ZF=1
,
SF=0
,
OF=0
,
PF=1
,
AF=0
EAX = F23456CE (十六进制)
EDX = 20000001 CF=1
EAX = D23456CC
CF=0,ZF=0,SF=1,OF=0,PF=1,AF=0
EAX = D2345705
CF =0,ZF=0,SF=0,OF=0,PF=1,AF=1
EDX = 2000FF01
CF=1,ZF=0,SF=1,OF=0,PF=1,AF=1
EDX = 2000FF00
CF=0,ZF=1,SF=0,OF=0,PF=1,AF=0
@续前页