汇编语言_入门经典教材-230页 汇编入门(7 讲)
发布时间:2024-11-12
发布时间:2024-11-12
汇编入门(7 讲)
时间:2009-5-16 8:12:26
核心提示:第 5 章微机CPU 的指令系统指令系统确定了CPU 所能完成的功能,是用 汇编语言进行程序设计的最基本部分。如果不熟悉汇编指令的功能及其有关规定,那么,肯 定不能灵活运用汇编语言。所以,本章的内容是学习本课程的重点和难点。5.1 汇编语言 指令格式为了介绍指令系统中指令的功能,先要清楚汇编语言是如何书写指令的...
第5章微机CPU的指令系统
指令系统确定了CPU 所能完成的功能,是用汇编语言进行程序设计的最基本部分。如 果不熟悉汇编指令的功能及其有关规定,那么,肯定不能灵活运用汇编语言。所以,本章的 内容是学习本课程的重点和难点。
5.1 汇编语言指令格式
为了介绍指令系统中指令的功能,先要清楚汇编语言是如何书写指令的,这就象在学习 高级语言程序设计时,要清楚高级语言语句的语义、语法及其相关规定一样。
5.1.1 指令格式
汇编语言的指令格式如下:
指令助忆符 [ 操作数1 [, 操作数2 [, 操作数3]]] [; 注释]
指令助忆符体现该指令的功能,它对应一条二进制编码的机器指令。指令的操作数个数 由该指令的确定,可以没有操作数,也可以有一个、二个或三个操作数。绝大多数指令的操 作数要显式的写出来,但也有指令的操作数是隐含的,不需要在指令中写出。 当指令含有操作数,并要求在指令中显式地写出来时,则在书写时必须遵守: 指令助忆符和操作数之间要有分隔符,分隔符可以是若干个空格或TAB 键; 如果指令含有多个操作数,那么,操作数之间要用逗号"," 分开。
指令后面还可以书写注释内容,不过,要在注释之前书写分号";"。
5.1.2了解指令的几个方面
在学习汇编指令时,指令的功能无疑是我们学习和掌握的重点,但要准确、有效地运用 这些指令,我们还要熟悉系统对每条指令的一些规定或约束。
归纳起来,对指令还要掌握以下几个方面内容:
、要求指令操作数的寻址方式;
、指令对标志位的影响、标志位对指令的影响;
、指令的执行时间,对可完成同样功能的指令,要选用执行时间短的指令(见附 录2 )。
5.2、指令系统
指令系统是CPU 指令的集合,CPU 除了具有计算功能的指令外,还有实现其它功能的 指令,也有为某种特殊的应用而增设的指令。
通常,把指令按其功能分成以下几大类:
数据传送指令
标志位操作指令
算术运算指令
逻辑运算指令
移位操作指令
位操作指令
比较运算指令
下面,我们逐一介绍每类指令中
的指令。
循环指令
转移指令
条件设置字节指令
字符串操作指令
ASCII-BCD 码运算调整指令
处理器指令
5.2.1 数据传送指令
数据传送指令又分为:传送指令、交换指令、地址传送指令、堆栈操作指令、转换指令 和I/O 指令等。
除了标志位操作指令SAHF 和POPF 指令外,本类的其它指令都不影响标志位。
1 、传送指令MOV(Move Instruction)
传送指令是使用最频繁的指令,它相对于高级语言里的赋值语句。指令的格式如下: MOV Reg/Mem, Reg/Mem/Imm
其中:Reg—Register(寄存器),Mem—Memory(存储器),Imm—Immediate( 立即数),它 们可以是8 位、16 位或32 位( 特别指出其位数的除外) 。在本网络课件的网页中,都将采用上
述缩写,此后不再说明。
指令的功能是把源操作数(第二操作数)的值传给目的操作数(第一操作数)。指令执行后, 目的操作数的值被改变,而源操作数的值不变。在存储单元是该指令的一个操作数时,该操 作数的寻址方式可以是任意一种存储单元寻址方式。
下面列举几组正确的指令例子:
源操作数是寄存器
MOV CH, AL MOV BP, SP MOV ECX, EBX
MOV DS, AX MOV [BX], CH MOV [BX+SI], AX
源操作数是存储单元
MOV AL, [100H] MOV BX, ES:[DI] MOV EDX, [BX]
MOV BX, VARW MOV AX, [BX+SI] MOV CH, [BX+DI+100H]
其中:VA R W 是字类型内存变量(下同)。
源操作数是立即数
MOV AL, 89H MOV BX, -100H MOV EDX, 12345678H
MOV VARW, 200H MOV [BX], 2345H MOV [BX+DI], 1234H
在汇编语言中,主要的数据传送方式如图5.1所示。虽然一条 MOV指令能实现其中大 多数的数据传送方式,但也存在MOV指令不能实现的传送方式。
对MOV指令有以下几条具体规定,其中有些规定对其它指令也同样有效。
1) 、两个操作数的数据类型要相同,要同为8 位、16位或32位;如:MOV BL, AX等是 不正确的;
2) 、两个操作数不能同时为段寄存器,如:MOV ES, DS等;
3) 、代码段寄存器 CS不能为目的操作数,但可作为源操作数,如:指令 MOV CS, AX
等不正确,但指令MOV AX, CS等是正确的;
4) 、立即数不能直接传给段寄存器,如:MOV DS, 100H等;
5) 、立即数不能作为目的操作数,如:MOV 100H, AX等;
6) 、指令指针IP ,不能作为MOV指令的操作数;
7) 、两个操作数不能同时为存储单元,如:M O V VA R A , VA R B等,其中VA R A 和VA R B
是同数据类型的内存变量。
对于规定2 、4 和7 ,我们可以用通用寄存器作为中转来达到最终目的。表5.1列举一个可
行的解决方案,尽供参考。读者可考虑用其它办法来完成同样的功能。
表5.1 MOV 指令的变通方法
功能描述不正确的指令可选的解决方法
把DS的值传送给ES MOV ES, DS MOV AX, DS
MOV ES, AX
把100H传给DS MOV DS, 100H MOV AX, 100H
MOV DS, AX
把字变量VA R B 的值传送
给字变量VA R A
MOV VARA, VARB MOV AX, VARB
MOV VARA, AX
对于情况1 :不同位数数据之间的传送问题,在80386 及其以后的 CPU 中,增加一组新 的指令——传送-填充指令,它可把位数少的源操作数传送给位数多的目的操作数,多出的 部分按指令的规定进行填充。
2 、传送—填充指令(Move-and-Fill Instruction)
传送—填充指令是把位数短的源操作数传送给位数长的目的操作数。指令格式如下: MOVSX/MOVZX Reg/Mem, Reg/Mem/Imm ;80386+
其中:80386+表示80386及其之后的CPU ,其它类似符号含义类同,不再说明。
指令的主要功能和限制与MOV指令类似,不同之处是:在传送时,对目的操作数的高 位进行填充。根据其填充方式,又分为:符号填充和零填充。
传送—填充指令的功能如图5.2所示。
、符号填充指令MOVSX(Move with Sign-Extend)
MOVSX的填充方式是:用源操作数的符号位来填充目的操作数的高位数据位。
、零填充指令MOVZX(Move with Zero-Extend)
MOVZX 的填充方式是:恒用0 来填充目的操作数的高位数据位。
例5.1 已知:AL=87H,指令 MOVSX CX, AL ,MOVZX DX, AL执行后,问CX和DX 的值是什么?
解:根据传送-填充指令的填充方式可知:
指令MOVSX CX, AL 执行后,(CX)=0FF87H ,指令MOVZX DX, AL 执行后,
(DX)=0087H 。
从上例可看出,两条指令的源操作数完全一样,但因为它们的填充方式不同,所得到的 结果而就不同。
试比较下列指令,分析它们执行结果的相同和不同之处:
MOV AX, 87H MOVSX AX, 87H MOVZX AX, 87H
3 、交换指令XCHG(Exchange Instruction)
交换指令XCHG 是两个寄存器,寄存器和内存变
量之间内容的交换指令,两个操作数的数据类型要相
同。其指令格式如下:
XCHG Reg/Mem, Reg/Mem
该指令的功能和MOV指令不同,后者是一个操作
数的内容被修改,而前者是两个操作数都会发生改变。
寄存器不能是段寄存器,两个操作数也不能同时为内存
变量。
XCHG 指令的功能如图5.3所示。
例5.2 已知:AX=5678H ,BX=1234H ,指令 XCHG AX, BX执行后,AX和BX的值是什 么?
解:这是两个寄存器内容进行交换,指令执行后,有:(AX)=1234H ,(BX)=5678H 。
4 、取有效地址指令LEA(Load Effective Address)
指令LEA 是把一个内存变量的有效地址送给指定的寄存
器。其指令格式如下:
LEA Reg, Mem
该指令通常用来对指针或变址寄存器BX、DI或SI 等置初
值之用。其功能如右图所示。
例如:
BUFF
ER
DB 100 DUP(?)
LEA BX, BUFFER ; 把字节变量BUFFER 在数据段内的偏移量送给BX
问题:指令“LEA BX BUFFER”和“MOV BX, OFFSET BUFFER”的执行效果是一样的 吗?指令“LEA BX,[BX+200]”和“MOV BX,OFFSET [BX+200]”二者都正确吗?
5 、取段寄存器指令(Load Segment Instruction)
该组指令的功能是把内存单元的一个“低字”传送给指令中指定的16位寄存器,把随后的 一个“高字”传给相应的段寄存器(DS 、ES、FS、GS和SS)。其指令格式如下:
LDS/LES/LFS/LGS/LSS Reg, Mem
指令LDS(Load Data Segment Register)和LES (Load Extra Segment Register) 在8086CPU 中就存在,而LFS 和LGS(Load Extra Segment Register)、LSS (Load Stack Segment Register) 是80386及其以后 CPU 中才有的指令。
若Reg 是16 位寄存器,那么,Men 必须是32位指针;若 Reg 是32 位寄存器,那么,Men
必须是48位指针,其低32 位给指令中指定的寄存器,高16位给指令中的段寄存器。指令的执
行结果如图5.5所示。
例如:
POINTER DD 12345678H
LDS BX, POINTER
指令的执行结果如图5.5所示。各寄存器的内容分别为:(BX)=5678H ,(DS)=1234H。 下面控件是学习和掌握MOV、MOVSX/MOVZX、XCHG 、LEA 、LDS/LES/LFS/LGS/LSS 指令的,它可检查用户输入这些指令的合法性,并对合法的指令显示其执行的结果。 注意:如果指令中含有表示内存单元的寻址方式,那么其控件中的" 内存单元的类型" 即表示该指令中内存单元的数据类型。
6 、堆栈操作指令(Stack Operation Instruction)
堆栈是一个重要的数据结构,它具有“先进后出”的特点,通常用来保存程序的返回地址。 它主要有两大类操作:进栈操作和出栈操作。
1) 、进栈操作
、PUSH(Push Word or Doubleword onto Stack)
指令格式:PUSH Reg/Mem
PUSH Imm ;80286+
一个字进栈,系统自动完成两步操作:SP←SP-2 ,(SP) ←操作数;
一个双字进栈,系统自动完成两步操作:ESP ←ESP-4,(ESP) ←操作数。
、PUSHA(Push All General Registers)
指令格式:PUSHA ;80286+
其功能是依次把寄存器AX、CX、DX、BX、SP、BP、SI 和DI等压栈。
、PUSHAD(Push All 32-bit General Registers)
指令格式:PUSHAD ;80386+
其功能是把寄存器EAX、ECX、EDX、EBX、ESP 、EBP 、ESI 和EDI 等压栈。
2) 、出栈操作
、POP(Pop Word or Doubleword off Stack)
指令格式:POP Reg/Mem
弹出一个字,系统自动完成两步操作:操作数←(SP) ,SP←SP-2 ;
弹出一个双字,系统自动完成两步操作:操作数←(ESP) ,ESP ←ESP-4。
、POPA(Pop All General Registers)
指令格式:POPA ;80286+
其功能是依次把寄存器DI、SI 、BP、SP、BX、DX、CX和AX等弹出栈。其实,
程序员不用记住它们的具体顺序,只要与指令PUSHA对称使用就可以了。
、POPAD(Pop All 32-bit General Registers)
指令格式:POPAD ;80386+
其功能是依次把寄存器EDI 、ESI、EBP 、ESP 、EBX、EDX、ECX和EAX等弹出
栈,它与PUSHAD 对称使用即可。
7 、转换指令XLAT(Translate Instruction)
转换指令有两个隐含操作数BX和AL。指令格式如
下:
XLAT/XLATB
其功能是把BX 的值作为内存字节数组首地址、下
标为AL的数组元素的值传送给AL。其功能描述的表达
式是:AL←BX[AL],其功能示意图如图5.6所示。
8 、I/O 指令
有关I/O 指令将在第8.1.2节——I/O 指令——中介绍,在此从略。
5.2.2 标志位操作指令
标志位操作指令是一组对标志位置位、复位、保存和恢复等操作的指令。
1 、进位CF操作指令
、清进位指令CLC(Clear Carry Flag):CF←0
、置进位指令STC(Set Carry Flag):CF←1
、进位取反指令CMC(Complement Carry Flag):CF←not CF
2 、方向位DF操作指令
、清方向位指令CLD(Clear Direction Flag) :DF←0
、置方向位指令STD(Set Direction Flag) :DF←1
3 、中断允许位IF 操作指令
、清中断允许位指令CLI(Clear Interrupt Flag):IF ←0
其功能是不允许可屏蔽的外部中断来中断其后程序段的执行。
、置中断允许位指令STI(Set Interrupt Flag):IF ←1
其功能是恢复可屏蔽的外部中断的中断响应功能,通常是与 CLI 成对使用的。
4 、取标志位操作指令
、LAHF(Load AH from Flags):AH←Flags的低8 位
、SAHF(Store AH in Flags):Flags的低8 位←AH
5 、标志位堆栈操作指令
、PUSHF/PUSHFD(Push Flags onto Stack) :把16位/32位标志寄存器进栈;
、POPF/POPFD(Pop Flags off Stack):把16位/32 位标志寄存器出栈;
6 、逻辑操作指令的小结
下面是学习标志位指令的控件,浏览者可以运用此类指令,观看标志寄存器的相应变化。
5.2.3 算术运算指令
算术运算指令是反映CPU 计算能力的一组指令,也是编程时经常使用的一组指令。它 包括:加、减、乘、除及其相关的辅助指令。
该组指令的操作数可以是8 位、16 位和32 位(80386+) 。当存储单元是该类指令的操作数 时,该操作数的寻址方式可以是任意一种存储单元寻址方式。
1 、加法指令
、加法指令ADD(ADD Binary Numbers Instruction)
指令的格式:ADD Reg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数的值加到目的操作数中。
、带进位加指令ADC(ADD With Carry Instruction)
指令的格式:ADC Reg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数和进位标志位CF的值(0/1) 一起加到目的操作数中。
、加1 指令INC(Increment by 1 Instruction)
指令的格式:INC Reg/Mem
受影响的标志位:AF、OF、PF、SF和ZF,不影响CF
指令的功能是把操作数的值加1 。
、交换加指令XADD(Exchange and Add)
指令的格式:XADD Reg/Mem, Reg ;80486+
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是先交换两个操作数的值,再进行算术“加”法操作。
例5.3 已知有二个32位数d1 和d2(用数据类型 DD说明),编写程序片段把d2 的值加到d1 中。
解:32位数d1 和d2 在内存中如下所示。
……
方法1 :用16 位寄存器编写程序
MO
V
AX, word ptr d1 ; 由于d1 是双字类型,必须使用强制类型说明符。以下同。
MO
V
DX, word ptr d1+2 ;(DX,AX) 构成一个32位数据
AD
D
AX, word ptr d2 ; 低字相加
AD
DX, word ptr d2+2 ; 高字相加。在低字相加时,有可能会产生“进位”
MO
V
word ptr d1, AX ; 低字送给d1 的低字
MO
V
word ptr d1+2, DX ; 高字送给d1 的高字
方法2 :用32 位寄存器编写程序
MO
V
EAX, d1
AD
D
EAX, d2
MO
V
d1, EAX
从上面两段程序不难看出:用32位寄存器来处理32 位数据显得简单、明了,而16位微机 虽然也能处理32位数据,但做起来就要复杂一些。
下面是学习和掌握加法类指令的控件,可模拟执行 ADD、ADC、INC 、XADD 、CLC 、 STC 和CMC等指令。用鼠标左键单击寄存器列表框中指定的寄存器,则可修改其值。后面 其它控件的有关操作与此相一致,不再说明。
2 、减法指令
、减法指令SUB(Subtract Binary Values Instruction)
指令的格式:SUB Reg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是从目的操作数中减去源操作数。
、带借位减SBB(Subtract with Borrow Instruction)
指令的格式:SBB Reg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数和标志位CF的值从目的操作数中一起减去。
、减1 指令DEC(Decrement by 1 Instruction)
指令的格式:DEC Reg/Mem
受影响的标志位:AF、OF、PF、SF和ZF,不影响CF
指令的功能是把操作数的值减去1 。
、求补指令NEG(Negate Instruction)
指令的格式:NEG Reg/Mem
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能:操作数=0-操作数,即改变操作数的正负号。
例5.4 已知有二个32位数d1 和d2 ,编写程序片段从 d1 中减去d2 的值。
解:
方法1 :用16 位寄存器编写程序
MO
V
AX, word ptr d1 ; 取低字
MO
V
DX, word ptr d1+2 ; 取高字,(DX,AX) 构成一个32位数据
SUB AX, word ptr d2 ;低字相减
SBB DX, word ptr d2+2 ;高字相减。在低字相减时,有可能会产生“借位”
MO
V
word ptr d1, AX ; 低字送给d1 的低字
MO
V
word ptr d1+2, DX ; 高字送给d1 的高字
方法2 :用32 位寄存器编写程序
MO
V
EAX, d1
SUB EAX, d2
MO
V
d1, EAX
下面是学习和掌握减法类指令的控件,可模拟执行SUB 、SBB 、DEC 、NEG、CLC 、 STC 和CMC等指令。
3 、乘法指令
计算机的乘法指令分为无符号乘法指令和有符号乘法指令,它们的唯一区别就在于:数 据的最高位是作为“数值”参与运算,还是作为“符号位”参与运算。
乘法指令的被乘数都是隐含操作数,乘数在指令中显式地写出来。CPU 会根据乘数是8 位、16位,还是32位操作数,来自动选用被乘数:AL、AX或EAX。
指令的功能是把显式操作数和隐含操作数相乘,并把乘积存入相应的寄存器中。 、无符号数乘法指令MUL(Unsigned Multiply Instruction)
指令的格式:MUL Reg/Mem
受影响的标志位:CF和OF(AF 、PF、SF和ZF无定义)
指令的功能是把显式操作数和隐含操作数(都作为无符号数) 相乘,所得的乘积按表
5.2的对应关系存放。
表5.2 乘法指令中乘数、被乘数和乘积的对应关系
乘数位数隐含的被乘数乘积的存放位置举例
8 位 AL AX MUL BL
16位 AX DX-AX MUL BX
32位 EAX EDX-EAX MUL ECX
、有符号数乘法指令IMUL(Signed Integer Mu ltiply Instruction)
IMU
L
Reg/Mem
IMU
L
Reg, Imm ;80286+
IMU
L
Reg, Reg, Imm ;80286+
指令的格
式:
IMU
L
Reg, Reg/Mem ;80386+
受影响的标志位:CF和OF(AF 、PF、SF和ZF无定义)
1) 、指令格式1——该指令的功能是把显式操作数和隐含操作数相乘,所得的乘积按表
5.2的对应关系存放。
2) 、指令格式2——其寄存器必须是16位/32 位通用寄存器,其计算方式为:
Reg ← Reg × Imm
3) 、指令格式3——其寄存器只能是16位通用寄存器,其计算方式为:
Reg1
← Reg
2
×Imm 或 Reg
1
← Mem×Imm
4) 、指令格式4——其寄存器必须是16位/32 位通用寄存器,其计算方式为:
Reg1
← Reg
1
×Reg
2
或 Reg
1
← Reg
1
×Mem
在指令格式2~4 中,各操作数的位数要一致。如果乘积超过目标寄存器所能存储的范围, 则系统将置溢出标志OF为1 。
下面是学习和掌握乘法类指令的控件,可模拟执行MUL和IMUL 等指令。
4 、除法指令
除法指令的被除数是隐含操作数,除数在指令中显式地写出来。CPU 会根据除数是8位、 16位,还是32 位,来自动选用被除数 AX、DX-AX,还是EDX-EAX。
除法指令功能是用显式操作数去除隐含操作数,可得到商和余数。当除数为0 ,或商超 出数据类型所能表示的范围时,系统会自动产生0 号中断。
、无符号数除法指令DIV(Unsigned Divide Instruction)
指令的格式:DIV Reg/Mem
指令的功能是用显式操作数去除隐含操作数(都作为无符号数),所得商和余数按表
5.3的对应关系存放。指令对标志位的影响无定义。
、有符号数除法指令IDIV(Signed Integer Di vide Instruction)
指令的格式:IDIV Reg/Mem
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是用显式操作数去除隐含操作数(都作为有符号数),所得商和余数的对应关 系见表5.3。
表5.3 除法指令除数、被除数、商和余数的对应关系
除数位数隐含的被除数商余数举例
8 位 AX AL AH DIV BH
16位 DX-AX AX DX DIV BX
32位 EDX-EAX EAX EDX DIV ECX
5 、类型转换指令
在作有符号除法时,有时需要把短位数的被除数转换成位数更长的数据类型。比如,要 用BL中的数据去除 AL,但根据除法指令的规定:除数是8 位,则被除数必须是 AX,于是 就涉及到AH的取值问题。
为了方便说明,假设:(AH)=1H ,(AL)=90H=-112D ,(BL)=10H。
1) 、在作除法运算前,必须处理AH的原有内容
假设在作除法时,不管AH 中的值,这时,(AH 、AL)/BL的商是19H ,但我们知道:
AL/BL 的商应是-7 ,这就导致:计算结果不是所预期的结果,所以,在作除法运算前,程序
员必须要处理AH中的值。
2) 、作无符号数除法时
可强置AH的值为0 ,于是,可得到正确的结果。
3) 、作有符号数除法时
如果强置AH为0 ,则AX=0090H ,这时,AX/BL的商为9 ,显然结果也不正确。 如果把AL的符号位1 ,扩展到 AH中,得:AX=0FF90H=-112D,这时,AX/BL的商就 是我们所要的正确结果。
综上所述,因为在进行有符号数除法时存在隐含操作数数据类型转换的问题,所以,系 统提供了四条数据类型转换指令:CBW、CWD、CWDE 和CDQ。
、字节转换为字指令CBW(Convent Byte to Word)
指令的格式:CBW
该指令的隐含操作数为AH 和AL。其功能是用AL的符号位去填充AH,即:当
AL为正数,则AH=0,否则,AH=0FFH。
指令的执行不影响任何标志位。
、字转换为双字指令CWD(Convent Word to Doubleword)
指令的格式:CWD
该指令的隐含操作数为DX 和AX,其功能是用AX 的符号位去填充DX。指令的
执行不影响任何标志位。
、字转换为扩展的双字指令CWDE(Convent Word to Extended Doubleword)
指令的格式:CWDE ;80386+
该指令的隐含操作数为DX和AX,其功能是用AX的符号位填充EAX的高字位。
指令的执行不影响任何标志位。
、双字转换为四字指令CDQ(Convent Doubleword to Quadword)
指令的格式:CDQ ;80386+
该指令的隐含操作数为EDX和EAX,指令的功能是用EAX的符号位填充EDX。
指令的执行不影响任何标志位。
下面是学习和掌握除法类指令的控件,可模拟执行 DIV 、IDIV、CBW、CWD、CWDE 和CDQ等指令。
例5.5 编写程序段,完成下面计算公式,并把所得的商和余数分别存入 X 和Y 中(其中:
A ,
B ,C ,X 和Y 都是有符号的字变量)。
(C - 120 + A*B) / C
解:
A DW ?
B DW ?
C DW ?
X DW ?
Y DW ?
MO
V
AX, C
SUB AX, 120D ;书写指令“ADD AX, -120D”也可以
CWD
MO
V
CX, DX
MO
V
BX, AX ;(CX, BX)←(DX, AX) ,调度寄存器,为作乘法准备必要的寄存器
MO
V
AX, A
IMU
L
B ;(DX, AX) ←A*B
AD
D
AX, BX ;计算32位二进制之和,为作除法作准备
AD
C
DX, CX
IDI
V
C ;AX是商,DX是余数
MO X, AX ;分别保存商和余数到指定的字变量单元里
V
MO
V
Y, DX
汇编入门(8 讲)
时间:2009-5-16 8:19:24
核心提示:5.2.4 逻辑运算指令逻辑运算指令是另一组重要的指令,它包括:逻辑与
(AND) 、逻辑或(OR)、逻辑非(NOT) 和异或指令(XOR) ,逻辑运算指令也是经常使用的指令。 1 、逻辑与操作指令AND(Logical AND Instruction) 指令的格式:AND Reg/Mem, Reg/Mem/Im...
5.2.4 逻辑运算指令
逻辑运算指令是另一组重要的指令,它包括:逻辑与(AND)、逻辑或(OR)、逻辑非(NOT) 和异或指令(XOR),逻辑运算指令也是经常使用的指令。
1 、逻辑与操作指令AND(Logical AND Instruction)
指令的格式:AND Reg/Mem, Reg/Mem/Imm
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF 无定义)
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑 “与操作”,操作结果存入目标操作数中。
例5.6 已知(BH)=67H ,要求把其的第0、1 和5 位置为0 。
解:可以构造一个立即数,其第0 、1和5 位的值为0 ,其它位的值
为1 ,该立即数即为:0DCH 或11011100B ,然后用指令"AND
BH, 0DCH "来实现此功能。
其计算过程如右图所示。
2 、逻辑或操作指令OR(Logical OR Instruction)
指令的格式:OR Reg/Mem, Reg/Mem/Imm
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF 无定义)
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑" 或操作",操作结果存入目标操作数中。
例5.7 已知(BL)=46H,要求把其的第1、3 、4 和6 位置为1 。
解:构造一个立即数,使其第1 、3 、4 和6 位的值为1 ,其它位的
值为0 ,该立即数即为:5AH 或01011010B ,然后用指令"OR
BL, 5AH"来实现此功能。
其计算过程如右图所示。
3 、逻辑非操作指令NOT(Logical NOT Instruction)
指令的格式:NOT Reg/Mem
其功能是把操作数中的每位变反,即:1 ←0 ,0←1 。指令的执行不影响任何标志位。 例5.8 已知(AL)=46H,执行指令“NOT AL”后,AL的值是什么?
解:执行该指令后,(AL)=0B9H 。其计算过程如下所示。
4 、逻辑异或操作指令XOR(Exclusive OR Instruction)
指令的格式:XOR Reg/Mem, Reg/Mem/Imm
受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF 无定义)
指令的功能是把源操作数中的每位二进制与目的操作数中的相应二进制进行逻辑" 异或操作",操作结果存入目标操作数中。
例5.9 已知(AH)=46H ,要求把其的第0、2 、5 和7 位的二进制值变反。
解:构造一个立即数,使其第0 、2 、5 和7 位的值为1 ,其它位的
值为0 ,该立即数即为:0A5H 或10100101B ,然后再用指令
"XOR AH, 0A5H"来实现此功能。
其计算过程如右图所示。
5 、逻辑操作指令的小结
下面是学习和掌握逻辑类指令的控件,可模拟执行AND、OR、NOT和XOR等指令。
5.2.5 移位操作指令
移位操作指令是一组经常使用的指令,它包括算术移位、逻辑移位、双精度移位、循环 移位和带进位的循环移位等五大类。
移位指令都有指定移动二进制位数的操作数,该操作数可以是立即数或 CL的值。在8086 中,该立即数只能为1 ,但在其后的 CPU 中,该立即数可以是1··31之内的数。
1、算术移位指令
算术移位指令有:算术左移SAL(Shift Algebraic Left)和算术右移SAR (Shift Algebraic Right)。它们的指令格式如下:
SAL/SAR Reg/Mem, CL/Imm
受影响的标志位:CF、OF、PF、SF和ZF(AF 无定义)。
算术移位指令的功能描述如下,具体功能下图(a)、(b)所示。
算术左移SAL 把目的操作数的低位向高位移,空出的低位补0 ;
算术右移 SAR 把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。
例5.10 已知(AH)=12H ,(BL)=0A9H ,试给出分别用算术左移和右移指令移动1 位后,寄存 器AH和BL的内容。
解:用算术左移和右移指令移动1 位后,寄存器 AH和BL的结果如下表所示。 操作数的初值执行的指令执行后操作数的内容
(AH)=12H SAL AH, 1 (AH)=24H
(BL)=0A9H SAL BL, 1 (BL)=52H
(AH)=12H SAR AH, 1 (AH)=09H
(BL)=0A9H SAR BL, 1 (BL)=0D4H
下面是学习和理解算术移位指令的控件。它简单、直观地表达了该移位指令的功能,通 过它,学习者可准确地掌握计算机系统中该移位指令的含义。
在该控件中,操作者可随机生成第一操作数,也可自行输入之。为了便于比较,在执行
指令前,把原操作数的内容存入“操作前的数据”中。
思考题:下面有两组指令序列,问每组指令执行后,寄存器AX的不会变化吗? SAL
AX, 1
SAR
AX, 1
或
SAR AX, 1
SAL AX, 1
2、逻辑移位指令
此组指令有:逻辑左移 SHL(Shift Logical Left) 和逻辑右移 SHR (Shift Logical Right) 。它 们的指令格式如下:
SHL/SHR Reg/Mem, CL/Imm
受影响的标志位:CF、OF、PF、SF和ZF(AF 无定义)。
逻辑左移/ 右移指令只有它们的移位方向不同,移位后空出的位都补0 。它们的具体功能 下图(a)、(b)所示。
例5.11 已知(AH)=12H ,(BL)=0A9H ,试给出分别用逻辑左移和右移指令移动1 位后,寄存
器AH和BL的内容。
解:用算术左移和右移指令移动1 位后,寄存器 AH和BL的结果如下表所示。 操作数的初值执行的指令
执行后操作数的内
容
(AH)=12H SHL AH, 1 (AH)=24H
(BL)=0A9H SHL BL, 1 (BL)=52H
(AH)=12H SHR AH, 1 (AH)=09H
(BL)=0A9H SHR BL, 1 (BL)=54H
学习和理解逻辑移位指令的控件。
3、双精度移位指令
此组指令有:双精度左移SHLD(Shift Left Double) 和双精度右移SHRD(Shift Right Double)。它们都是具有三个操作数的指令,其指令的格式如下:
SHLD/SHRD Reg/Mem, Reg, CL/Imm ;80386+
其中:第一操作数是一个16位/32 位的寄存器或存储单元;第二操作数(与前者具有相同 位数)一定是寄存器;第三操作数是移动的位数,它可由CL或一个立即数来确定。
在执行SHLD 指令时,第一操作数向左移n 位,其“空出”的低位由第二操作数的高n 位来填补,但第二操作数自己不移动、不改变。
在执行SHRD 指令时,第一操作数向右移n 位,其“空出”的高位由第二操作数的低n 位来填补,但第二操作数自己也不移动、不改变。
SHLD 和SHRD 指令的移位功能示意图如图5.8所示。
受影响的标志位:CF、OF、PF、SF和ZF(AF 无定义)
下面是几个双精度移位的例子及其执行结果。
双精度移位指令指令操作数的初值指令执行后的结果
SHLD AX, BX, 1 (AX)=1234H ,(BX)=8765H (AX)=2469H
SHLD AX, BX, 3 (AX)=1234H ,(BX)=8765H (AX)=91A4H
SHRD AX, BX, 2 (AX)=1234H ,(BX)=8765H (AX)=448DH
SHRD AX, BX, 4 (AX)=1234H ,(BX)=8765H (AX)=5123H
学习和理解双精度移位指令的控件。
4、循环移位指令
循环移位指令有:循环左移ROL(Rotate Left)和循环右移 ROR(Rotate Right) 。
指令的格式:ROL/ROR Reg/Mem, CL/Imm
受影响的标志位:CF和OF
循环左移/ 右移指令只是移位方向不同,它们移出的位不仅要进入 CF,而且还要填补空 出的位。具体功能如下图(a)、(b)所示。
下面是几个循环移位的例子及其执行结果。
循环移位指令指令操作数的初值指令执行后的结果
ROL AX, 1 (AX)=6789H (AX)=0CF12H
ROL AX, 3 (AX)=6789H (AX)=3C4BH
ROR AX, 2 (AX)=6789H (AX)=59E2H
ROR AX, 4 (AX)=6789H (AX)=9678H
学习和理解不带进位的循环移位指令的控件。
5、带进位的循环移位指令
带进位的循环移位指令有:带进位的循环左移 RCL(Rotate Left Through Carry)和带进位 的循环右移RCR(Rotate Right) 。
指令的格式:RCL/RCR Reg/Mem, CL/Imm
受影响的标志位:CF和OF
带进位的循环左移/右移指令只有移位的方向不同,它们都用原 CF的值填补空出的位, 移出的位再进入CF。具体功能如下图(a)、(b)所示。
下面是几个带进位循环移位的例子及其执行结果。
双精度移动指令指令操作数的初值
指令执行后的结
果
RCL AX, 1 CF=0,(AX)=0ABCDH (AX)=579AH
RCL AX, 1 CF=1,(AX)=0ABCDH (AX)=579BH
RCR AX, 2 CF=0,(AX)=0ABCDH (AX)=AAF3H
RCR AX, 2 CF=1,(AX)=0ABCDH (AX)=EAF3H
例5.12 编写指令序列把由 DX和AX组成的32位二进制算术左移、循环左移1 位。 解:
(DX,AX) 算术左移1 位指令序列 (DX,AX) 循环左移1 位指令序列