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

📄 汇005.txt

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

受影响的标志位:CF、OF、PF、SF和ZF(AF无定义)。

算术移位指令的功能描述如下,具体功能下图(a)、(b)所示。

算术左移SAL把目的操作数的低位向高位移,空出的低位补0;
  算术右移SAR把目的操作数的高位向低位移,空出的高位用最高位(符号位)填补。


 
 
(a)、SAL (b)、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)所示。


 
 
(a)、SHL (b)、SHR 

例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无定义)


 
 
(a)、SHLD
 (b)、SHRD
 

图5.8 双精度移位指令操作示意图

下面是几个双精度移位的例子及其执行结果。

双精度移位指令
 指令操作数的初值
 指令执行后的结果
 
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)所示。

  
(a)、ROL
 (b)、ROR
 

下面是几个循环移位的例子及其执行结果。

循环移位指令
 指令操作数的初值
 指令执行后的结果
 
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.2.6 位操作指令
1、位扫描指令(Bit Scan Instruction)

指令的格式:BSF/BSR Reg, Reg/Mem     ;80386+

受影响的标志位:ZF

位扫描指令是在第二个操作数中找第一个“1”的位置。如果找到,则该“1”的位置保存在第一操作数中,并置标志位ZF为1,否则,置标志位ZF为0。

根据位扫描的方向不同,指令分二种:正向扫描指令和逆向扫描指令。

、正向扫描指令BSF(Bit Scan Forward)从右向左扫描,即:从低位向高位扫描;
、逆向扫描指令BSR(Bit Scan Reverse)从左向右扫描,即:从高位向低位扫描。

 

(a) BSF
 

(b) BSR
  
例如:

MOV AX, 1234H
BSF CX, AX       ;指令执行后,(CX)=2
BSR CX, AX       ;指令执行后,(CX)=12

2、位检测指令(Bit Test Instruction)

指令的格式:BT/BTC/BTR/BTS Reg/Mem, Reg/Imm    ;80386+
受影响的标志位:CF

位检测指令是把第一个操作数中某一位的值传送给标志位CF,具体的哪一位由指令的第二操作数来确定。

根据指令中对具体位的处理不同,又分一下几种指令:

BT:把指定的位传送给CF;
BTC:把指定的位传送给CF后,还使该位变反;
BTR:把指定的位传送给CF后,还使该位变为0;
BTS:把指定的位传送给CF后,还使该位变为1;
 

图5.11 位检测指令的功能示意图
 

例如:假设(AX)=1234H,分别执行下面指令。

BT  AX, 2      ;指令执行后,CF=1,(AX)=1234h
BTC AX, 6       ;指令执行后,CF=0,(AX)=1274h
BTR AX, 10      ;指令执行后,CF=0,(AX)=1234h
BTS AX, 14      ;指令执行后,CF=0,(AX)=5234h

3、检测位指令TEST(Test Bits Instruction)

检测位指令是把二个操作数进行逻辑“与”操作,并根据运算结果设置相应的标志位,但并不保存该运算结果,所以,不会改变指令中的操作数。在该指令后,通常用JE、JNE、JZ和JNZ等条件转移指令。

指令的格式:TEST  Reg/Mem, Reg/Mem/Imm

受影响的标志位:CF(0)、OF(0)、PF、SF和ZF(AF无定义)

例如:

TEST AX, 1       ;测试AX的第0位
TEST CL, 10101B    ;测试CL的第0、2、4位

下面是学习和掌握乘法类指令的控件,可模拟执行BSF、BSR、BT、BTC、BTR、BTS和TEST等指令。
5.2.7 比较运算指令
在程序中,我们要时常根据某个变量或表达式的取值去执行不同指令,从而使程序表现出有不同的功能。为了配合这样的操作,在CPU的指令系统中提供了各种不同的比较指令。通过这些比较指令的执行来改变有关标志位,为进行条件转移提供依据。

1、比较指令CMP(Compare Instruction)

指令的格式:CMP Reg/Mem, Reg/Mem/Imm

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

指令的功能:用第二个操作数去减第一个操作数,并根据所得的差设置有关标志位,为随后的条件转移指令提供条件。但并不保存该差,所以,不会改变指令中的操作数。

2、比较交换指令(Compare And Exchange Instruction)

在数据传送类指令中,我们介绍了交换指令XCHG,它不管二个操作数的值是什么,都无条件地进行交换。而比较交换指令,是先进行比较,再根据比较的结果决定是否进行操作数的交换操作。

比较交换指令的功能:当二个操作数相等时,置标志位ZF为1;否则,把第一操作数的值赋给第二操作数,并置标志位ZF为0。

、8位/16位/32位比较交换指令

指令的格式:CMPXCHG Reg/Mem, AL/AX/EAX    ;80486+
受影响的标志位:AF、CF、OF、PF、SF和ZF
MASM 6.11中指令的描述与此不同,它没有限定第二操作数的要求。

、64位比较交换指令

该指令只有一个操作数,第二个操作数EDX:EAX是隐含的。

指令的格式:CMPXCHG8B Reg/Mem      ;Pentium+
受影响的标志位:ZF

例如:假设(AX)=1234H,(BX)=1234H,(CX)=4321H。

CMPXCHG BX, AX    ;指令执行后,ZF=1
CMPXCHG CX, AX    ;指令执行后,ZF=0,(AX)=4321H,CX的值不变

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

参见后面第5.2.11节——字符串操作类指令——的叙述。
5.2.8 循环指令
循环结构是程序的三大结构之一。为了方便构成循环结构,汇编语言提供了多种循环指令,这些循环指令的循环次数都是保存在计数器CX或ECX中。除了CX或ECX可以决定循环是否结束外,有的循环指令还可由标志位ZF来决定是否结束循环。

在高级语言中,循环计数器可以递增,也可递减,但汇编语言中,CX或ECX只能递减,所以,循环计数器只能从大到小。在程序中,必须先把循环次数赋给循环计数器。

汇编语言的循环指令都是放在循环体的下面,在循环时,首先执行一次循环体,然后把循环计数器CX或ECX减1。当循环终止条件达到满足时,该循环指令下面的指令将是下一条被执行的指令,否则,程序将向上转到循环体的第一条指令。

在循环未终止,而向上转移时,规定:该转移只能是一个短转移,即偏移量不能超过128,也就是说循环体中所有指令码的字节数之和不能超过128。如果循环体过大,可以用后面介绍的“转移指令”来构造循环结构。

循环指令本身的执行不影响任何标志位。

1、循环指令(Loop Until Complete)

循环指令LOOP的一般格式:

LOOP 标号
LOOPW 标号      ;CX作为循环计数器,80386+
LOOPD 标号      ;ECX作为循环计数器,80386+

循环指令的功能描述:
 

图5.12 循环指令LOOP的功能示意图
 
 (CX)=(CX)-1或(ECX)=(ECX)-1; 
 如果(CX)≠0或(ECX)≠0,转向“标号”所指向的指令,否则,终止循环,执行该指令下面的指令。 

例5.13 编写一段程序,求1+2+…+1000之和,并把结果存入AX中。

解: 
 方法1:因为计数器CX只能递减,所以,可把求和式子改变为:1000+999+…+2+1。 
XOR AX, AX 
MOV CX, 1000D 
again: ADD AX, CX ;计算过程:1000+999+…+2+1 
LOOP again 
方法2:不用循环计数器进行累加,求和式子仍为:1+2+…+999+1000。 
XOR AX, AX 
MOV CX, 1000D 
MOV BX, 1 
again: ADD AX, BX ;计算过程:1+2+…+999+1000 
INC BX 
LOOP again 

从程序段的效果来看:方法1要比方法2好。
2、相等或为零循环指令(Loop While Equal or Loop While Zero)

⌨️ 快捷键说明

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