⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 汇005.txt

📁 会变语言实现的一些程序
💻 TXT
📖 第 1 页 / 共 5 页
字号:

图5.16 置字符串数据指令的功能示意图
 
3、字符串传送指令(Move String Instruction)

该指令是把指针DS:SI所指向的字节、字或双字传送给指针ES:DI所指向内存单元,并根据标志位DF对寄存器DI和SI作相应增减。该指令的执行不影响任何标志位。

指令的格式:MOVS  地址表达式1, 地址表达式2
MOVSB/MOVSW
MOVSD      ;80386+
 

图5.17 字符串传送指令的功能示意图
 4、输入字符串指令(Input String Instruction)

该指令是从某一指定的端口接受一个字符串,并存入一片存储单元之中。输入端口由DX指定,存储单元的首地址和读入数据的个数分别由ES:DI和CX来确定。在指令的执行过程中,还根据标志位DF对寄存器DI作相应增减。该指令不影响任何标志位。

与指令有关的操作数ES、DI、DX和CX等都是隐含操作数。

指令的格式:INS  地址表达式
INSB/INSW
INSD       ;80286+

5、输出字符串指令(Output String Instruction)

该指令是把一个字符串输入到指定的输出端口中。输出端口由DX指定,其输出数据的首地址和个数分别由DS:SI和CX来确定。在指令的执行过程中,还根据标志位DF对寄存器SI作相应增减。该指令的执行不影响任何标志位。

与指令有关的操作数DS、SI、DX和CX等都是隐含操作数。

指令的格式:OUTS  地址表达式
OUTSB/OUTSW
OUTSD      ;80286+

6、字符串比较指令(Compare String Instruction)

该指令是把指针DS:SI和ES:DI所指向字节、字或双字的值相减,并用所得到的差来设置有关的标志位。与此同时,变址寄存器SI和DI也将根据标志位DF的值作相应增减。

指令的格式:CMPS 地址表达式1, 地址表达式2
CMPSB/CMPSW
CMPSD      ;80386+

受影响的标志位:AF、CF、OF、PF、SF和ZF
 

图5.18 字符串比较指令的功能示意图
 

7、字符串扫描指令(Scan String Instruction)

该指令是用指针ES:DI所指向字节、字或双字的值与相应的AL、AX或EAX的值相减,用所得到的差来设置有关标志位。与此同时,变址寄存器DI还将根据标志位DF的值进行增减。

指令的格式:SCAS 地址表达式1
SCASB/SCASW
SCASD      ;80386+

受影响的标志位:AF、CF、OF、PF、SF和ZF
 8、重复字符串操作指令(Repeat String Instruction)

前面介绍了七种不同的字符串操作指令:取字符串数据、置字符串数据、字符串传送、输入字符串、输出字符串、字符串比较和字符串扫描等指令,所叙述是这些指令执行一次所具有的功能。但我们知道:每个字符串通常会有多个字符的,所以,就需要重复执行这些字符串操作指令。为了满足这种需求,指令系统提供了一组重复前缀指令。

虽然在这些字符串指令的前面都可以添加一个重复前缀指令,但由于指令执行结果的差异,对某个具体的字符串指令又不用重复前缀指令而改用其它循环来实现重复的需要。

重复字符串操作指令对标志位的影响是由被重复的字符串操作指令来决定。

重复前缀指令REP(Repeat String Instruction)

重复前缀指令是重复其后的字符串操作指令,重复的次数由CX来决定。其一般格式为:

REP LODS/LODSB/LODSW/LODSD
REP STOS/STOSB/STOSW/STOSD
REP MOVS/MOVSB/MOVSW/MOVSD
REP INS/ INSB/INSW/INSD
REP OUTS/OUTSB/OUTSW/OUTSD

重复前缀指令的执行步骤如下:

(1)、判断:CX=0;
(2)、如果CX=0,则结束重复操作,执行程序中的下一条指令;
(3)、否则,CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,在该指令执行完后,再转到步骤(1)。

从上面的重复前缀指令格式来看,虽然我们可以使用重复取字符串数据指令(第一组指令),但可能会因为指令的执行结果而在程序中几乎不被使用。

例5.20 编写一段程序,计算字符串“12345abcdefgh”中字符的ASCII之和。

解: 
MESS DB  '12345abcdefgh' ;在数据段中进行变量说明 
MOV AX, SEG MESS 
MOV DS, AX 
LEA SI, MESS ;用DS:SI来指向字符串的首地址 
MOV CX, 13D ;重复次数 
XOR BX, BX ;置求和的初值为0 
REP LODSB 

虽然指令“REP  LODSB”能从字符串中取出每个字符,但它是在一条指令中完成的,程序的其它指令根本无法处理每次取出的数据,指令的执行结果是:AL只保存最后一次所取出的字符'h'的ASCII码。

所以,为了实现本例的要求,不能使用重复前缀指令,而要把指令“REP  LODSB”改写成如下四条指令:

 XOR AH, AH ;为后面的累加作准备 
again: LODSB 
ADD BX, AX ;AL是被取出的字符,AH已被清0 
LOOP again 

条件重复前缀指令(Repeat String Conditionally)

条件重复前缀指令与前面的重复前缀指令功能相类似,所不同的是:其重复次数不仅由CX来决定,而且还会由标志位ZF来决定。根据ZF所起的作用又分为二种:相等重复前缀指令REPE/REPZ和不等重复前缀指令REPE/REPZ。

A、相等重复前缀指令的一般格式为:

REPE/REPZ SCAS/SCASB/SCASW/SCASD
REPE/REPZ CMPS/CMPSB/CMPSW/CMPSD

该重复前缀指令的执行步骤如下:

(1)、判断条件:CX≠0 且 ZF=1;
(2)、如果条件不成立,则结束重复操作,执行程序中的下一条指令;
(3)、否则,CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,在该指令执行完后,再转到步骤(1)。

B、不等重复前缀指令的一般格式为:

REPNE/REPNZ SCAS/SCASB/SCASW/SCASD
REPNE/REPNZ CMPS/CMPSB/CMPSW/CMPSD

该重复前缀指令的执行步骤如下:

(1)、判断条件:CX≠0 且 ZF=0;
(2)、如果条件不成立,则结束重复操作,执行程序中的下一条指令;
(3)、否则,CX=CX-1(不影响有关标志位),并执行其后的字符串操作指令,在该指令执行完后,再转到步骤(1)。
5.2.12 ASCII--BCD码运算调整指令
前面介绍的算术运算指令都是针对二进制数进行操作的指令,但对绝大多数人来说,十进制是最简单、熟悉的。为了方便按十进制数进行算术运算,指令系统专门提供了一组十进制运算调整指令。

虽然人们会觉得按十进制进行算术运算很自然,但计算机要化更多的时间来完成相应操作。在通常情况下,这组指令很少被程序员运用在实际的程序之中。所以,这组指令的使用率较低,可以根据需要有选择性地学习。

1、ASCII码加调整指令AAA(Ascii Adjust After Addition)

该指令是用于调整AL之值,该值是二个ASCII码字节相加之和。具体的调整规则如下:

、若AL的低四位大于9,或标志位AF=1,则,AH=AH+1,AL=AL+6,并置AF和CF为1,否则,只置AF和CF为0;
、清除AL的高四位。



图5.20 AAA指令执行过程示意图

指令的格式:AAA
受影响的标志位:AF和CF(OF、PF、SF和ZF等都是无定义)

例5.21 编写一段程序,完成二个15位十进制数X和Y之和,并把计算结果存入X之中。假设数据X和Y都是以字符串形式表示的。

解: 
X db "456407983123186" ;任意假设二个15位的大数 
Y db "326676709587211" 
CLC 
MOV SI, 14 ;用变址寄存器SI来从字符串的后面向前访问 
MOV CX, 15 ;因为它们是二个15位十进制数 
loop1: MOV AL, X[SI] 
ADC AL, Y[SI] ;把被加数加上 
AAA 
MOV X[SI], AL 
DEC SI 
LOOP loop1 ;15位十进制数相加完毕 
LEA BX, X ;下面5条指令是把X中的数据变成对应的字符 
MOV CX, 15 
loop2: ADD byte ptr [BX], '0' 
INC BX 
LOOP loop2 

从上例可以看出,其实任意位的十进制数也都是可以的,只要改变CX的值即可。

2、ASCII码减调整指令AAS(Ascii Adjust After Subtraction)

该指令是用于调整AL之值,该值是二个ASCII码字节相减之差。具体的调整规则如下:

、若AL的低四位大于9,或标志位CF=1,则,AH=AH-1,AL=AL-6,并置AF和CF为1,否则,只置AF和CF为0;
、清除AL的高四位。

指令的格式:AAS
受影响的标志位:AF和CF(OF、PF、SF和ZF等都是无定义)



图5.21 AAS指令执行过程示意图

  3、ASCII码乘调整指令AAM(Ascii Adjust After Multiplication)

该指令是用于调整寄存器AL之值,该值是由二个单BCD码字节用无符号乘指令MUL所得的积。其调整规则如下:

AH←AL/10(商),AL←AL%10(余数)

指令的格式:AAM
受影响的标志位:PF、SF和ZF(AF、CF和OF等都是无定义)

例如:

MOV AL, 9
MOV BL, 8
MUL BL       ;AL=72D
AAM         ;AH=7, AL=2

4、ASCII码除调整指令AAD(Ascii Adjust After Division)

该指令是在作除法前用于调整寄存器AH和AL之值,它是把二个寄存器中单BCD码组成一个十进制数值,为下面的除法作准备的。其调整规则如下:

AL←AH*10+AL,AH←0

指令的格式:AAD
受影响的标志位:PF、SF和ZF(AF、CF和OF等都是无定义)

例如:

MOV AX, 0502H
MOV BL, 10D
AAD         ;AH=0, AL=52D
DIV  BL       ;AH=2(余数), AL=5(商)
5、十进制数加调整指令DAA(Decimal Adjust After Addition)

该指令是用于调整AL的值,该值是由指令ADD或ADC运算二个压缩型BCD码所得到的结果。压缩型BCD码是一个字节存放二个BCD码,低四位和高四位都是一个BCD码。

其调整规则如下:

、如果AL的低四位大于9,或标志位AF=1,那么,AL=AL+6,并置AF=1;
、如果AL的高四位大于9,或CF=1,那么,AL=AL+60H,并置CF=1;
、如果以上两点都不成立,则,清除标志位AF和CF。

经过调整后,AL的值仍是压缩型BCD码,即:二个压缩型BCD码相加,并进行调整后,得到的结果还是压缩型BCD码。

指令的格式:DAA
受影响的标志位:AF、CF、PF、SF和ZF(OF无定义)

例如:

MOV AL, 43H
MOV BL, 29H
ADD AL, BL     ;AL=6BH,其不是压缩型的BCD码,因为低四位'B'不是BCD码
DAA         ;调整后,AL=72H,这是压缩型的BCD码,也有:43+29=72

6、十进制数减调整指令DAS(Decimal Adjust After Subtraction)

该指令也是用于调整AL的值,该值是由指令SUB或SBB运算二个压缩型BCD码所得到的结果。其调整规则如下:

、如果AL的低四位大于9,或标志位AF=1,那么,AL=AL-6,并置AF=1;
、如果AL的高四位大于9,或CF=1,那么,AL=AL-60H,并置CF=1;
、如果以上两点都不成立,则,清除标志位AF和CF。

经过调整后,AL的值仍是压缩型BCD码,即:二个压缩型BCD码相减,并进行调整后,得到的结果还是压缩型BCD码。

指令的格式:DAS
受影响的标志位:AF、CF、PF、SF和ZF(OF无定义)

例如:

MOV AL, 43H
MOV BL, 29H
SUB AL, BL    ;AL=1AH,其不是压缩型的BCD码,因为低四位'A'不是BCD码
DAS        ;调整后,AL=14H,这是压缩型的BCD码,也有:43-29=14
5.2.13 处理器指令
处理器指令是一组控制CPU工作方式的指令。这组指令的使用频率不高。

1、空操作指令NOP(No Operation Instruction)

该指令没有的显式操作数,主要起延迟下一条指令的执行。通常用执行指令“XCHG AX, AX”来代表它的执行。NOP指令的执行不影响任何标志位。

指令的格式:NOP

2、等待指令WAIT(Put Processor in Wait State Instruction)

该指令使CPU处于等待状态,直到协处理器(Coprocessor)完成运算,并用一个重启信号唤醒CPU为止。该指令的执行不影响任何标志位。

指令的格式:WAIT

3、暂停指令HLT(Enter Halt State Instruction)

在等待中断信号时,该指令使CPU处于暂停工作状态,CS:IP指向下一条待执行的指令。当产生了中断信号,CPU把CS和IP压栈,并转入中断处理程序。在中断处理程序执行完后,中断返回指令IRET弹出IP和CS,并唤醒CPU执行下条指令。

指令的格式:HLT

指令的执行不影响任何标志位。

4、封锁数据指令LOCK(Lock Bus Instruction)

该指令是一个前缀指令形式,在其后面跟一个具体的操作指令。LOCK指令可以保证是在其后指令执行过程中,禁止协处理器修改数据总线上的数据,起到独占总线的作用。该指令的执行不影响任何标志位。

指令的格式:LOCK INSTRUCTION
5.3 习题
5.1、书写正确的MOV指令,需要符合哪些规定?在32位CPU中,增加了什么指令来克服不同数据类型之间的数据传送?
 
5.2、简述指令MOV BX, 1234H、MOV BX, [1234]和MOV BX, offset [1234H]的功能和它们之间区别。
 
5.3、简述指令MOV BX, Data和MOV BX, offset Data之间的区别。
 
5.4、选择指令实现下列要求,OPN1 ← OPN2的含义:把操作数OPN2的值传送给OPN1。
 
1)、EBX ← EDX
3)、SI ← BX
5)、AL ← BH
7)、AX ← 13AH
9)、SI ← 1000H
 2)、BX ← CL
4)、DS ← AX
6)、AL ← 12H
8)、CX ← 0CDH                        (假设0CDH为无符号数)
10)、EBX ← 1200A2H 
5.5、PUSHA指令能把哪些寄存器压栈?它们进栈的顺序是什么?可用什么指令把这些寄存器依次弹出堆栈?
 
5.7、PUSHAD指令完成什么操作?它与什么操作的作用相反?
 
5.8、在16位/32位CPU中,标志位寄存器的内容进栈和出栈的指令是什么?
 
5.9、写出下列指令序列中每条指令的执行结果,请在Debug环境下验证之,并注意各标志位的变化情况。
 
MOV   BX, 23ABH
ADD   BL, 0ACH
MOV   AX, 23F5H
ADD   BH, AL
SBB    BX, AX
ADC   AX, 12H
SUB   BH, -9
 
5.10、假定DS=1123H,SS=1400H,BX=0200H,BP=1050H,DI=0400H,SI=0500H,LIST的偏移量为250H,试确定下面各指令访问内存单元的地址。
 
 1)、MOV AL, [1234H] 2)、MOV AX, [BX] 
3)、MOV [DI], AL 4)、MOV [2000H], AL 
5)、MOV AL, [BP+DI] 6)、MOV CX, [DI] 
7)、MOV EDX, [BP] 8)、MOV LIST[SI], EDX 
9

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -