乐趣区

关于asm:汇编语言中的指令系统

8086/8088 共有 92 条指令,正确理解和把握每一条指令的性能和格局,是汇编语言程序设计的根底。

一、指令系统概述

(一)指令分类

92 条指令形成了 8086/8088 指令系统,它们可分为六大类。

(1)传送类指令(Transfer instructions)。

(2)算术运算类指令(Arithmetic instructions)。

(3)位操作类指令(Bit manipulation instructions)。

(4)串操作类指令(String instructions)。

(5)程序转移类指令(Program transfer instructions)。

(6)处理器管制类指令(Processor Control instructions)。

(二)指令格局

8086/8088 指令系统中的指令有 3 种格局。

(1)双操作数指令:OPR DEST,SRC

(2)单操作数指令:OPR DEST

(3)无操作数指令:OPR

其中,OPR 是指令操作符,也称为指令助记符,它示意指令要执行何种操作。双操作数指令指定两个操作数,第一个为目标操作数,第二个为源操作数,两操作数之间要用逗号“,”分隔,它们的地位不能调换,操作的后果个别在目标操作数中。因而,目标操作数不能是常数,而只能是寄存器操作数或存储器操作数。语句执行后,目标操作数原来的内容将产生扭转,而源操作数的内容不会扭转。

单操作数指令只须要一个操作数,它或是源操作数(SRC),或是目标操作数(DEST)。

对于无操作数指令,尽管指令自身未指明操作数是什么、在哪里,但指令却隐含规定了操作数及寄存地点。

(三)指令规定

8086/8088 指令在应用时有较严格的规定,要正确地把握和使用这些指令,首先要精确地把握这些规定。8086/8088 汇编语言指令独特恪守如下规定。

(1)规定 1:除通用数据传送指令(MOV、PUSH、POP)之外,段寄存器不容许作为操作数。

(2)规定 2:段寄存器不能间接用立刻数赋值。

(3)规定 3:代码段寄存器 CS 和立刻数不能作为目标操作数。

(4)规定 4:指令中两个操作数不能同时为段寄存器。

(5)规定 5:指令中两个操作数不能同时为存储器操作数(串指令除处)。

(6)规定 6:指令中两个操作数的类型(字节类型或字类型等)必须统一。

(7)规定 7:指令中至多要有一个操作数的类型是明确的,否则须用操作符 PTR 长期指定操作数类型。

上面介绍 8086/8088 指令。

二、传送类指令

传送类指令共有 12 条,包含通用数据传送指令(MOV、PUSH、POP)、替换指令(XCHG)、查表指令(XLAT)、地址传送指令(LEA、LDS、LES)和标记传送指令(PUSHT、POPT、LAHF、SAHF)。它们能够将各种类型的操作数从源传送到目标,其传送路径见图 1。图中实线示意非法传送路径,虚线为非法传送路径。所有的传送类指令对标记位均无影响。

图 1 数据的传送路径

(一)通用数据传送指令

这种指令共有 3 条。

  1. 传送指令(Mov)

格局:MOV DEST,SRC

性能:把源操作数的内容传送给目标操作数,即 DEST←SRC。

阐明:当 MOV 指令执行完后,源操作数和目标操作数都将有雷同的内容,目标操作数原有的内容隐没。MOV 指令能够进行字节数据传送,也可进行字数据的传送。

例:

而上面的指令是非法的(参见指令规定):

  1. 进栈指令(Push Word Onto Stack)

格局:PUSH SRC

操作:

(1)堆栈指针减 2 指向新的栈顶,SP←SP-2。

(2)将给定的操作数放入 SP 批示的字单元中。

阐明:进栈指令的操作数是一个 16 位的寄存器操作数或存储器操作数,不容许是立刻数。

例:

  1. 出栈指令(Pop Word Off Stack Into Destination)

格局:POP DEST

操作:

(1)将栈顶的字数据送入操作数 DEST 中,DEST←(SP+1,SP)。

(2)堆栈指针加 2 指向新栈顶,SP←SP+2。

例:

通用数据传送指令的通用性在于它适宜所有的操作数,比方可应用段寄存器作为操作数,而除了这 3 条通用数据传送指令之外,任何 8088 指令都不能在指令中呈现段寄存器(见指令规定 1)。

(二)替换指令(Exchange)

格局:XCHG DEST,SRC

操作:将两个操作数的内容调换,即 (DEST)←→(SRC)。

例:

若进行两个内存单元 D1_BYTE 和 D2_BYTE 之间的数据交换,可用如下 3 条指令实现:

MOV   AL,D1_BYTE
XCHG  AL,D2_BYTE
XCHG  AL,D1_BYTE

上面的指令是非法的(参见指令规定):

(三)查表指令

格局:XLAT

性能:将数据段(DS)中偏移地址为 BX+AL 的内存字节单元的内容送入 AL 中,即 AL←(BX+AL)。

阐明:XLAT 指令用于查表。表的开始地址即表头地址由 BX 给出。AL 中的原始值是要查找的表中元素的地址位移量。

例如:如图 2 所示,在内存符号地址 TABLE 开始有一个 0~9 的数的平方表。如果要查 5 的平方值,把被查数 5 放入 AL 中(这正好就是它自身的平方值在表中寄存的位移量),将表头地址送入 BX 中(MOV BX,OFFSET TABLE),应用 XLAT 指令后在 AL 中就能失去 5 的平方值。

图 2 平方查示意意

(四)地址传送指令

这种指令共 3 条,它们不是传送存储器操作数的内容,而是传送它的地址(偏移量,段基值)。

  1. 装入无效地址(Load Effective Address)

格局:LEA DEST,SRC

性能:把源操作数的偏移量(即无效地址 EA)送给目标操作数的通用寄存器。本指令中 SRC 必须是一个存储器操作数,而 DEST 肯定是 16 位通用寄存器。

例:

  1. 装入地址指针(Load Address of Point)

地址指针的值是由 16 位段基值和 16 位偏移量两局部形成的,装入地址指针指令能用一条指令实现将寄存在内存中的地址指针值的段基值送入段寄存器,同时将偏移量局部送入指令规定的寄存器中。

格局:

(1)LDS DEST,SRC

(2)LES DEST,SRC

性能:将双字长存储器操作数 SRC 的低地址字单元内容送入指定的寄存器 DEST 中,而将双字长存储器操作数 SRC 的高地址字单元内容送入 DS(LDS)或 ES(LES)。

阐明:指令的目标操作数(DEST)要寄存地址指针的偏移值局部,因而,必须是一个 16 位通用寄存器,而 SRC 肯定是存储器操作数。

例如,设 SI 间址寄存器所指的内存单元寄存的数据如图 3 所示,若有上面指令:

LDS BX,[SI]

则该指令执行后,DS 内容为 9010H,BX 内容为 302FH。

图 3 LDS 指令的传送

(五)标记传送指令(Flags Transfer)

8086/8088 设计了 4 条指令专门用于标记寄存器的存取操作。它们都是无操作数指令。

  1. 取标记寄存器

格局:LAHF

性能:把标记寄存器的低 8 位传送给 AH 寄存器。

  1. 存储标记寄存器

格局:SAHF

性能:把寄存器 AH 中的第 7、6、4、2、0 位的内容别离送入标记寄存器 SF、ZF、AF、PF 和 CF 各标记位。标记寄存器 OF、DF、IF 和 TF 各位均不受影响。

  1. 标记进栈

格局:PUSHF

性能:首先把堆栈指针 SP 减 2,而后将 16 位标记寄存器的全部内容(含所有标记位)送入 SP 指向的堆栈顶部。标记寄存器中各标记位自身不受影响。

  1. 标记出栈

格局:POPF

性能:首先将现行堆栈顶部(由 SP 决定)的一个字的内容送入标记寄存器,而后 SP+2。标记寄存器中各标记位的状态,由从堆栈中弹出字的相应位的内容所决定。

标记寄存器中只有少数几个标记位(如 CF、DF、IF)有专门的指令进行置 0 或置 1 操作,其余大部分标记位都没有指令间接对它们进行设置或批改。例如要批改 SF,那么可首先用 LAHF 指令把含有 SF 标记位的标记寄存器低 8 位送入 AH,而后对 AH 的第 7 位(对应 SF 位)进行批改或设置,再用 SAHF 指令送回标记寄存器。

三、算术运算类指令

8086/8088 的算术运算指令提供加、减、乘、除四类运算,可对 4 种数据进行解决。这 4 种数据如下。

(1)无符号二进制数。

(2)带符号二进制数。

(3)无符号组合十进制数(组合 BCD 码)。

(4)无符号非组合十进制数(非组合 BCD 码)。

(一)二进制加法运算指令

二进制加法指令有 3 条,指令格局和性能如下。

  1. 加法指令

格局:ADD DEST,SCR

性能:将源操作数 SCR 和目标操作数 DEST 相加,后果存入 DEST 中,即 DEST←DEST+SCR。

阐明:加法指令能够进行字节或字的加法,其后果放在目标操作数中,源操作数原有的内容不变(对任何指令都是如此)。

例:

ADD  AX,X
ADD  AL,0A4H
  1. 带进位加指令

格局:ADC DEST,SCR

性能:将源操作数 SCR、目标操作数 DEST 及进位标记 CF 位相加,后果存入 DEST 中,即 DEST←DEST+SCR+CF。

阐明:ADC 指令次要用于大于 16 位(多字节)数的加法中。例如,有一个 32 位二进制数已寄存在 AX(高 16 位)和 BX(低 16 位)中,现要加上常数 208A9F88H,可用上面两条指令来实现:

ADD  BX,9F88H
ADC  AX,208AH

其中,第一条指令把低 16 位常数 9F88H 加在 BX 中,若它们相加高 16 位有进位时,则把进位记录在 CF 中。在第二条指令实现高 16 位加时,用 ADC 指令同时把低 16 位的进位一起加上。

  1. 加 1 指令

格局:INC DEST

性能:将目标操作数 DEST 本身加 1,后果存入 DEST 中,即 DEST←DEST+1。

阐明:INC 指令次要用于某些计数器的计数和地址指针值的批改。

例:

INC  SI  ;SI←SI+1

留神:加法指令会按其执行后果设置 6 个状态标记的状态,但 INC 指令对进位标记 CF 无影响。

(二)二进制减法运算指令

  1. 减法指令

格局:SUB DEST,SRC

性能:将目标操作数 DEST 内容减去源操作数 SRC 内容,后果送入 DEST 中,即 DEST←DEST-SRC。

  1. 带借位减法指令

格局:SBB DEST,SRC

性能:将目标操作数 DEST 内容减去源操作数 SRC 内容及 CF 位,后果送入 DEST 中,即 DEST←DEST-SRC-CF。

阐明:SBB 指令在应用上相似于 ADC 指令,次要用于大于 16 位的多精度数的减法,把低位局部相减的借位引入高位局部的减法中。

  1. 减 1 指令

格局:DEC DEST

性能:将目标操作数 DEST 内容减 1,后果送入 DEST 中,即 DEST←DEST-1。

阐明:DEC 指令应用上相似于 INC 指令,次要用于计数和批改地址指针,但方向与 INC 指令相同。DEC 操作不影响进位标记 CF。

  1. 比拟指令

格局:CMP DEST,SRC

性能:目标操作数 DEST 减去源操作数 SRC,即 DEST←DEST-SRC。

阐明:CMP 指令将两个操作数相减,但相减的后果并不保留,两个操作数都放弃原值不变,只是将相减后果的特色反映在各个状态标记位上。比方当 CMP 指令执行后,如果标记位 ZF=1,阐明被比拟的两数相等,能够在 CMP 指令后,用单标记判断转移指令或条件判断转移指令来确定比拟的后果(大于、小于、等于)。

  1. 取补指令

格局:NEG DEST

性能:零减去目标操作数 DEST,后果存入目标操作数 DEST,即 DEST←0-DEST。

阐明:NEG 指令是求操作数的正数,即扭转操作数的符号,这对带符号数来说就是求其补码。因而 NEG 也叫取补指令。NEG 对标记位影响有非凡规定,如果被取补的操作数非 0,NEG 操作后,CF 置 1,否则 CF=0。

(三)二进制乘法运算指令

  1. 无符号数乘法指令

格局:MUL SRC

性能:若 SRC 为字节长度,则 AX←AL×SRC;若 SRC 为字长度,则 DX:AX←AX×SRC。

阐明:乘法指令格局中只呈现源操作数,依据这个操作数的类型(字节类型或字类型)决定是 8 位乘还是 16 位乘。因而,SRC 不能是立刻数(立刻数无类型属性),而目标操作数(被乘数)隐含约定为累加器 AL(8 位乘)或 AX(16 位乘),运算的后果约定在 AX 中(8 位乘法的积)或 DX:AX 中(16 位乘法的积),如图 4 所示。

图 4 乘法指令操作示意

  1. 带符号数乘法指令

格局:IMUL SRC

性能:性能同 MUL 指令

阐明:乘法指令对标记的影响有非凡规定,它只影响标记位 CF 和 OF。对于 MUL,如果乘积的高半部(8 位乘时为 AH,16 位乘时为 DX)为零,CF=0,OF=0;否则 CF=1,OF=1(示意 AH 或 DX 中有乘积的有效数字)。对于 IMUL,若积的高半部是低半部的符号扩大,则 CF=0,OF=0;否则 CF 和 OF 均为 1。

(四)二进制除法指令

二进制除法运算指令包含无符号数除法(DIV)和带符号数除法(IDIV)。对带符号数来说,还有两条符号扩大指令(CBW、CDQ)。

  1. 无符号数除法指令

格局:DIV SRC

性能:若 SRC 为字数据,则 AX/SRC,AL←商,AH←余数;若 SRC 为字数据,则 DX:AX/SRC,AX←商,DX←余数。

  1. 带符号数除法指令

格局:IDIV SRC

性能:同 DIV 指令。

阐明:同乘法指令相似,除法指令中的操作数 SRC 为除数,它不能是立刻数。目标操作数(被除数)也有两种状况,当除数为 8 位时被除数隐含为 AX,运算后果商约定在 AL 中,余数约定在 AH 中;当除数为 16 位时,被除数隐含在 DX:AX,运算后果约定在 AX 中,余数在 DX 中,如图 5 所示。

图 5 除法指令操作示意

留神:

(1)除法指令对标记位的影响无意义。

(2)除数必须足够大,使得商值小于等于 8 位或 16 位数示意的范畴;否则,将产生除法谬误。

  1. 字节扩大指令

格局:CBW

性能:对 AL 中的带符号数进行符号扩大。若 AL<0,AH=0FFH,否则 AH=0。

(五)十进制算术运算指令

大家晓得,计算机只能解决二进制信息,但在理论的生产和生存中,人们习惯应用十进制数。因而,须要计算机解决的原始数据大部分是十进制数据。人们心愿计算机能接管这些十进制数,并将解决的后果以十进制模式输入。这时从内部来看,如同计算机在进行十进制数运算一样。

每一位十进制数在计算机外部,通常是用 4 位二进制数示意的,它是十进制数的二进制编码。8086/8088 CPU 实现十进制运算的办法是仍将这些十进制数(BCD 码)看作二进制数,应用二进制加、减、乘、除指令进行运算,不过在运算后(或前)用调整指令进行调整以失去十进制(BCD 码)后果。故此,针对非组合和组合 BCD 码,8086/8088 提供了 6 条算术运算相应的 BCD 码调整指令。

  1. 非组合十进制调整指令

(1)加法调整指令(ASCII Adjust for Addition)。

格局:AAA

性能:若 AL 中的低 4 位值大于 9 或 AF=1,则将 AL 加 6 和 AH 加 1,并将 AF 和 CF 置 1,而后将 AL 的高 4 位清 0;否则只进行清 AL 高 4 位操作。

受影响的状态标记位:AF、CF(OF、ZF 和 PF 的状态不确定)。

(2)减法调整指令(ASCII Adjust for Subtraction)。

格局:AAS

性能:如果 AL 中的低 4 位大于 9 或 AF=1,那么就将 AL 减 6 且 AH 减 1,并将 AF 和 CF 置 1,而后将 AL 的高 4 位清 0;否则只进行清 AL 高 4 位操作。

受影响的状态标记位:AF、CF(OF、SF、ZF 和 PF 的状态不确定)。

(3)乘法调整指令(ASCII Adjust for Multiply)。

格局:AAM

性能:将 AL 中的内容除以 10,商送入 AH 中,余数送入 AL 中。

受影响的状态标记位:SF、ZF、PF(OF、AF、CF 状态不确定)

阐明:AAM 指令将两个无效的非组合十进制数相乘后失去的乘积调整为一个无效的非组合十进制数,AAM 指令执行后被调整字节的高 4 位为 0。

(4)除法调整指令(ASCII Adjust for Division)。

格局:AAD

性能:将 AH 中的内容乘以 10 后与 AL 相加,后果存到 AL 中,而后将 AH 清 0。

受影响的状态标记位:SF、ZF、PF(OF、AF、CF 状态不确定)。

阐明:AAD 指令在两个无效的非组合十进制数做除法之前调整 AL 中的内容,以使除法失去的商数为一个无效的非组合十进制数。为了使跟在其后的 DIV 指令能产生一个正确的后果,AH 必须为 0。除法指令执行后,商寄存在 AL 中,余数寄存在 AH 中,它们的高 4 位都为 0。

  1. 组合十进制调整指令

(1)加法调整指令(Decimal Adjust for Addition)。

格局:DAA

性能:如果 AL 中的低 4 位大于 9 或 AF=1,那么就将 AL 加 6,并将 AF 置 1;如果 AL 的高 4 位大于 9 或 CF=1,则将 60H 加到 AL 中,并将 CF 置 1。

受影响的状态标记位:OF、SF、ZF、AF、PF、CF。

(2)减法调整指令(Decimal Adjust for Subtraction)。

格局:DAS

性能:如果 AL 中的低 4 位大于 9 或 AF=1,那么就将 AL 减 6,并将 AF 置 1;如果 AL 的高 4 位大于 9 或 CF=1,则从 AL 中减去 60H,并将 CF 置 1。

受影响的状态标记位:SF、ZF、AF、PF、CF(OF 不确定)。

总结:

所谓十进制算术运算(BCD 码运算)指令,就是在二进制算术运算指令之后加上一个相应的调整指令(除法指令是先调整后跟除法指令),因而,能够将十进制算术运算指令看成一个由两条指令形成的复合指令,例如,组合十进制加法指令为:

留神:调整指令仅对累加器 AL 的内容进行调整,因而,在进行十进制算术运算时,目标操作数必须应用累加器。

四、位操作指令

位操作指令是指按位进行操作的指令,包含逻辑运算指令、移位和循环移位指令两种。

(一)逻辑运算指令(logical)

共有 5 条逻辑运算指令,它们的指令格局和性能如下。

  1. 逻辑“与”指令

格局:AND DEST,SRC

性能:DEST←DEST∧SRC;CF=0,OF=0。

  1. 逻辑“或”指令

格局:OR DEST,SRC

性能:DEST←DEST∨SRC;CF=0,OF=0。

  1. 逻辑“异或”指令

格局:XOR DEST,SRC

性能:DEST←DEST⊕SRC;CF=0。OF=0。

  1. 逻辑“非”指令

格局:NOT DEST

性能:DEST←DEST。

  1. 测试指令

格局:TEST DEST,SRC

性能:DEST∧SRC。

总结:

(1)逻辑操作指令对标记位的影响有非凡规定。

① NOT 指令对标记位没有影响。

② 执行除 NOT 指令之外的逻辑指令后,OF 和 CF 两个标记都被清 0,而 AF 状态不确定,其余标记反映操作后果的状态。

(2)TEST 指令对两个操作数进行“与”操作,但不保留“与”的后果,只是通过标记状态的判断,得出测试后果。次要用于测试一个操作数(目标操作数)某一位或几位的状态。

(3)逻辑指令次要用于字节或字中某些位的组合、拆散或位设置等。

例:

(二)移位和循环移位指令

移位和循环移位指令共有 8 条,它们的指令格局和操作如表 4 所示。

表 4 移位和循环移位指令

阐明:

(1)目标操作数 dest 能够是通用寄存器或存储器操作数,cnt 为移位次数,能够是 1,或由 CL 指出(移位次数大于 1 时必须用 CL 给出移位次数),位移完结后 CL 值不变。

(2)CF 的值总是最初一次被移入的值。

(3)移位指令影响标记位 CF、OF、SF、ZF。而循环移位指令仅影响 CF 和 OF 位。

(4)对 OF 影响的规定是:在挪动 1 位的状况下,如果移位后操作数的最高位扭转了,OF 就被置 1,否则 OF 被置 0。若移位次数大于 1,那么 OF 不确定。

五、转移类指令

在 8086/8088 汇编语言程序中,指令执行的程序由代码段寄存器 CS 和指令指针 IP 所确定,在失常状况下,程序总是程序执行的。CPU 每执行完一条指令,就主动批改 IP 的值使之指向下一条指令。转移指令能够实现程序流向的管制和转移,这是通过扭转 CS 和 IP 值实现的。若转移在同一段内进行(段内转移),就只须要批改 IP 值;若是在两个段之间进行转移(段间转移),则 CS 和 IP 都须要批改。

依据转移的范畴将转移分为 3 类。

(1)远转移(段间转移):转移的指标地址为 32 位。能够实现一个段到任意其余代码段的转移。

(2)近转移(段内转移):转移的指标地址为 16 位。转移的间隔限定在以后段内,最大 64KB。

(3)短转移:转移的指标地址为 8 位。转移范畴限定在从转移指令的下一条指令算起的 -128~+127 个字节的地址空间以内。

转移类指令包含无条件转移指令、条件转移指令、循环控制指令、调用 / 返回指令、中断指令等。本节只介绍前 3 种。

(一)无条件转移指令

无条件转移指令仅有一条,它能够实现远转移、近转移或短转移。格局:JMP targ

性能:

(1)段内转移:IP←指标的偏移地址。

(2)段间转移:IP←指标的偏移地址,CS←指标所处代码段基址。

阐明:JMP 指令使程序无条件地转移到指标 targ 指明的地址处执行。依据 targ 的类型会主动产生一个远转移、近转移或短转移指令。指令中的 targ 能够是标号、寄存器或存储器操作数,JMP 对标记位无影响。

例:

(二)条件转移指令

条件转移指令是依据 CPU 中状态标记位以后的状态决定程序执行的流程,既可能产生程序转移,也可能不产生程序转移。条件转移指令是以对不同的状态标记的测试为条件,如果条件成立,则管制转移到指令中所给出的转移指标,如果条件不成立,程序将程序执行。

条件转移指令共有 18 条,它们都是两个字节长的指令,其中一个字节为操作码,另一个字节为转移指标的偏移量(本指令的下条指令与指标的绝对字节间隔)。因为绝对转移指标仅 8 位长,因而,所有的条件转移指令都仅能实现短转移。

条件转移指令见表 5,这些指令对标记位无影响。条件转移指令中的 targ 是要转向的指令语句标号,经汇编产生一个绝对位移量,是一个 8 位带符号数。

条件转移指令个别用在算术运算、逻辑运算,或某些比拟、测试指令之后,依据这些指令操作后的后果(反映在各状态标记上)判断转移。

表 5 条件转移指令

(三)循环控制指令

在转移类指令中,有 3 条循环控制指令,用来反对循环构造程序设计。它们和条件转移指令雷同,仅能实现短转移。这 3 条指令均约定用 CX 作为循环次数计数器,因而,这种指令只能用在循环次数已知的循环程序中。在执行循环控制指令时,主动对 CX 进行减 1 操作,并主动判断 CX 是否减为 0,这样,用循环控制指令比用条件转移指令来管制循环更简洁、不便。

  1. 无条件循环控制指令

格局:LOOP targ

性能:若 CX-1≠0 则转移,否则退出循环。相当于两条指令:

DEC  CX
JNZ  targ

该指令使循环体无条件循环 CX 中指定的次数。

  1. 相等循环控制指令

格局:LOOPZ targ 或 LOOPE targ

性能:若 CX-1≠0(规定的循环次数没完)且 ZF=1(比拟相等)则转移,否则退出循环。

  1. 不等循环控制指令

格局:LOOPNZ targ 或 LOOPNE targ

性能:若 CX-1≠0(规定的循环次数没完)且 ZF=0(比拟不等)则转移,否则退出循环。

另外还有一条 JCXZ 指令也可用于循环管制。

格局:JCXZ targ

性能:若 CX=0 则转移,否则执行后续指令。

六、串操作指令

用字节或字组成的一组数据称为数据串。组成数据串的字节或字称为数据串元素。如字符串‘abcdef’是一个字节数据串,串中每一个字符的 ASCII 码形成了该数据串的元素。

对数据串的传送、比拟、搜寻、存取等操作是十分典型、罕用的操作。为此,汇编语言设计了 5 条专门用于上述操作的串指令。并且设计了 3 个反复前缀,它们加在串操作指令前,使得用一条指令就可实现一个循环程序的性能,而且不必思考指针如何挪动、循环如何管制等问题,极大中央便了程序设计。

(一)串操作指令的隐含规定

5 条串操作指令隐含地应用了雷同的寄存器、标记位和符号。隐含规定如下。

(1)源串指针:DS:SI,目标串指针:ES:DI。

(2)反复次数计数器:CX(加反复前缀时)。

(3)操作方向:DF=0,正向(SI、DI 主动增量批改);DF=1,负向(SI、DI 主动减量批改)。操作方向可用 CLD 和 STD 指令设置。

(4)指令 SCAS、LODS、STOS 约定累加器为一个操作数。

(二)串操作指令格局与性能

串操作指令能够实现字节和字串的操作,指令别离如下。

  1. 串传送指令

(1)MOVSB;将源串一字节传送到目标串,并主动批改指针值。

;[ES:DI]←[DS:SI],SI←SI±1,DI←DI±1

(2)MOVSW;将源串一字传送到目标串,并主动批改指针值。

;[ES:DI]←[DS:SI],SI←SI±2,DI←DI±2

  1. 串比拟指令

(1)CMPSB;源串一字节与目标串一字节相减比拟,并主动批改指针值。

;[DS:SI]-[ES:DI],SI←SI±1,DI←DI±1

(2)CMPSW;源串一字与目标串一字相减比拟,并主动批改指针值。

;[DS:SI]-[ES:DI],SI←SI±2,DI←DI±2

  1. 串搜寻指令

(1)SCASB;将 AL 内容与目标串内容进行比拟,并主动批改指针值。

;AL- [ES:DI],DI←DI±1

(2)SCASW;AX- [ES:DI],DI←DI±2

  1. 从源串中取数指令

(1)LODSB;AL←[DS:SI],SI←SI±1

(2)LODSW;AX←[DS:SI],SI←SI±2

  1. 往目标串中存数指令

(1)STOSB;[ES:DI] ←AL,DI←DI±1

(2)STOSW;[ES:DI] ←AX,DI←DI±2

留神:

(1)批改地址指针时加减由 DF 状态决定。DF=0 时增量批改,DF=1 时减量批改。

(2)5 条串操作指令都有另一种带操作数的格局:

MOVS dest,src

CMPS dest,src

SCAS dest

LODS src

STOS dest

因上述格局不罕用,所以在指令格局中未列出。

(三)串操作的反复前缀

串操作指令与一般指令相比,只是多了一个主动批改地址指针的性能。退出反复前缀,才使得串操作指令得以反复执行。

  1. 无条件反复前缀指令

格局:REP

性能:使 REP 后的指令无条件反复 CX 值指定的次数。用于 MOVS、STOS 指令前。

  1. 相等反复前缀指令

格局:REPZ/REPE

性能:当 CX≠0(规定的反复次数没完)同时 ZF=1(比拟相等)时,反复执行该前缀后的指令,否则,终止(CX 已为 0)或停止(CX≠0,但 ZF=0)反复。该前缀只能用于 CMPS 和 SCAS 前,在两个数据串中找出不同的元素。

  1. 不相等反复前缀指令

格局:REPNZ/REPNE

性能:当 CX≠0(规定的反复次数没完)同时 ZF=0(比拟不相等)时,反复执行该前缀后的指令;否则,终止(CX 已为 0)或停止(CX≠0,但 ZF=1)反复。该前缀只能用于 CMPS 和 SCAS 前,在两个数据串中找出雷同的元素。

留神:

(1)CX 是否为 0 的判断(即反复操作是否实现的检测)是在串操作之前进行的,因而,若 CX 的初值为 0,则串操作一次也不会执行。

(2)对比拟和搜寻的串操作完结,有两种可能:一种是反复了规定的次数(CX 已为 0),也没有找到要找的元素;另一种是中途或最初找到了要找的元素。这两种状况可通过对标记 ZF 的判断确定:如果 ZF 的状态和反复的条件雷同(不相等反复时 ZF=0,相等反复时 ZF=1),则为第一种状况,否则为第二种状况。

(3)操作完结后,SI、DI 中为下一个元素的偏移地址,其方向由 DF 确定。

上面通过例子领会一下串操作指令的利用。

【例 1】 将以 SBUF 为首址的 200 字节的数据块传送到 DBUF 开始的区域,可用以下程序段实现:

CLD
LEA  SI,SBUF
LEA  DI,DBUF
MOV  CX,200
REP  MOVSB

【例 2】 STRING 为一个 30 字节长的字符串,查找该串中最初一个字母‘B’,若找到将其地址存入 BX 中,否则将 0 送入 BX。

这个问题能够应用带不相等反复前缀的串搜寻指令实现。要查找串中最初一个字母‘B’,可从前面开始反向查找。程序段如下:

七、处理器管制类指令

这一类指令次要包含以下 3 种。

(一)标记位操作指令

它们均是无操作数指令,即它们的操作数隐含在标记寄存器中某些标记位上。能间接操作(批改)的标记位有 CF、IF 和 DF。

(1)革除进位标记指令:CLC;置 CF=0

(2)进位标记置位指令:STC;置 CF=1

(3)进位标记取反指令:CMC;CF 取反

(4)革除方向标记指令:CLD;置 DF=0(正向)

(5)方向标记置位指令:STD;置 DF=1(反向)

(6)革除中断标记(关中断)指令:CLI;置 IF=0

(7)中断标记置位(开中断)指令:STI;置 IF=1

留神:上述 7 条指令性能是把对应的标记地位 0、置 1 或取反而不扭转其余标记位。

(二)空操作指令

格局:NOP

性能:这条指令使 CPU 执行一次空操作,不影响任何寄存器、存储单元和标记位,仅占据 CPU 的 3 个时钟周期。在软件延时程序中,可用 NOP 指令作大量的延时调整。

(三)内部同步指令

这方面指令有 WAIT、ESC、LOCK、HLT 等。这些指令的执行波及其余常识,故这里不探讨这些指令。在理论利用中,须要用这些指令时,可查阅无关材料。

原文:汇编语言中的指令系统

(完)

退出移动版