Pentium的指令系统(3)——算术运算指令

时间:2024-03-21 11:33:36

对有符号和无符号数的分析

1.对加法或减法来说,无符号数和有符号数可采用同一套指令,乘法和除法不行;
无符号数和有符号数采用同一套加法指令及减法指令有两个条件:
1.要求参与运算的两个数同为无符号数或同为有符号数
2.用不同的方法检测无符号数或有符号数的运算结果是否溢出(无符号CF,有符号(OF+CF))

算术运算指令可以对8位、16位或32位数据进行运算,其中,源操作数可以是立即数、通用寄存器或存储器中的数,而目的操作数可为通用寄存器或存储器中的值。

加法类指令ADD/ADC/INC

(1)不带进位位的加法指令ADD
ADD指令用来执行2个字节、2个字或2个双字的相加操作,运算时不考虑CF位,结果放在原来存放目的操作数的地方
Pentium的指令系统(3)——算术运算指令
作用:
1.将CX中的内容和1000H相加,结果放在CX中
2.DI和SI的内容相加,结果放在DI中
3.BX+DI和BX+DI+1所指两单元内容和AX中的数相加,结果放在BX+DI和BX+DI+1所指的单元中
4.BX+2000H~BX+2003H所指4单元的内容和EAX的内容相加,结果放到EAX中

注意:
ADD指令影响标志寄存器中的状态标志

(2)带进位位的加法指令ADC
带进位位的加法指令ADC在形式和功能上都和ADD指令类似,只有一点区别,即执行ADC指令时,将进位标志CF的值加在和中
Pentium的指令系统(3)——算术运算指令
作用:
1.AX和SI中的内容以及CF的值相加,结果放在AX中
2.DX的内容和SI与SI+1所指单元的内容以及CF的值相加,结果放在DX中
3.BX的内容和立即数3000H以及CF的值相加,结果放BX中

注意:
1.ADC指令用于多字节加法运算
2.ADC指令影响标志寄存器的状态位

(3)增量指令INC
INC指令只有1个操作数,指令在执行时,将操作数的内容加1,这条指令一般用在循环程序中修改指针和循环次数
Pentium的指令系统(3)——算术运算指令
作用:
1.将AL中的内容+1
2.将ECX中的内容+1
3.将BX+DI+500所指单元的内容+1

注意:
1.不影响进位标志CF

减法类指令SUB/SBB/DEC和CMP

(1)不考虑借位的减法指令SUB
SUB指令完成2个数的相减,操作数可为带符号或不带符号的字节、字或双字
Pentium的指令系统(3)——算术运算指令
作用:
1.将EBX中的双字减去ECX中的双字,结果放在EBX中
2.将SS段的BP+2所指单元中的值减去CL中的值,结果在BP+2所指的堆栈单元中
3.将DI和DI+1所指单元的值减去1000H,结果放在DI和DI+1所指单元

(2)考虑借位的减法指令SBB
考虑CF的值,就是两数相减时向高位产生的借位,SBB在执行减法运算时,是用被减数减去减数,并减去低位字节产生的借位,主要用于多字节减法运算中,当分步进行减法时,可用SBB指令传递借位
Pentium的指令系统(3)——算术运算指令
作用:
1.将AX的内容减去2530H,并减去进位位CF的值,存放到AX中
2.将EDI+2和EDI+3所指单元的内容减去1000H,并减去进位位CF的值,存放到DI+2和DI+3所指的单元中

(3)减量指令DEC
DEC指令只有1个操作数,执行时,将操作数的值减1
Pentium的指令系统(3)——算术运算指令
作用:
1.将EBX的内容减1,再送回到EBX中
2.将AX的内容减1,再送回AX中
3.将DI+2所指的单元的内容减1,结果送回此单元

注意:
不影响进位标志CF

(4)比较指令CMP
CMP指令也是执行两个数的相减操作,但不送回相减的结果,只是使结果影响标志位
Pentium的指令系统(3)——算术运算指令
作用:
1.将AX的内容和2000H相比较,结果影响标志位
2.将累加器内容和4个存储单元的数进行比较
3.将EDX和EDI的内容进行比较

比较方法:
两操作数相等:标志位ZF=1
两数不等:
(1)对无符号数的比较:CF为0表示无借位,即被减数大;CF为1表示借位,即减数大
(2)对有符号数的比较:OF与SF的值相同,则被减数大;OF与SF的值不同,则被减数小

乘法指令MUL/IMUL

(1)进行乘法操作时,两个8位数据相乘,会得到一个16位的乘积。
(2)在执行乘法指令时,有一个乘数总是放在AL、AX或EAX中,另外,将DX看作是AX的扩展,将EDX看成是EAX的拓展。故得到16位的乘积时放入AX;32位的乘积时高16位放入DX,低16位放入AX中(Pentium中同时复制并放到EAX中);64位乘积时高32位放入EDX,低32位放入EAX。
(3)对有符号和无符号指令分开

(一)无符号的乘法指令MUL
Pentium的指令系统(3)——算术运算指令
作用:
1.AX中和CX中的两个16位数相乘,结果在DX和AX中
2.AL和DI所指单元的两个8位数相乘,结果放在AX中
3.AX和SI与SI+1所指单元的两个16位数相乘,结果放在DX和AX中

注意:
MUL 10 ×,因为无法知晓立即数的字节长度

(二)有符号数的乘法指令IMUL
Pentium的指令系统(3)——算术运算指令
作用:
1.将AL和CL中的两个有符号数相乘,结果放AX中
2.AL中8位有符号数和BX所指单元中的8位有符号数相乘,结果放AX中
3.AX中16位有符号数和DI与DI+1所指单元的16位有符号数相乘,结果放DX和AX中

注意:
1.乘法运算指令会影响标志位CF和OF

除法指令DIV/IDIV

(1)除法运算时,规定除数必须为被除数的一半字长,即被除数16位时,除数为8位;
(2)16位的被除数放在AX中;32位的被除数放在DX和AX中,DX中放高位,AX中放地位;
(3)当被除数为16位时,除数为8位时,得到8位的商放在AL中,8位的余数放在AH中;当被除数为32位时,除数为16位,得到16位的商放在AX中,16位的余数放在DX中;

(一)无符号数的除法指令DIV
Pentium的指令系统(3)——算术运算指令
作用:
1.AX中的数据除以CL中的数据,商在AL,余数在AH中
2.DX和AX中的32位数除以DI和DI+1指向单元的16位数,商在AX中,余数在DX中

注意:
1.对字节为除数的操作,商最大为255,对字为除数的操作,商最大为65535;

(二)有符号的除法指令IDIV
Pentium的指令系统(3)——算术运算指令
作用:
1.将DX和AX中的32位数除以BX中的16位数,商在AX中,余数在DX中
2.将AX中的16位数除以DI指向单元的8位数,商在AL中,余数在AH中

注意:
1.除法运算时,要求被除数的数位是除数数位的2倍,否则就必须将被除数进行拓展,如果没有进行拓展,就会得到错误的结果。对于无符号数相除来说,被除数的拓展很简单,只需要将AH、DX、EDX这几个寄存器清零就行了。对于有符号数来说,AH、DX、EDX的拓展就是符号拓展,即把AL中的最高位拓展到AH的8位中,把AX中的最高位拓展到DX中,或把EAX的最高位拓展到EDX中。
2.用IDIV指令时,如是一个字除以一个字节,则商的范围为-128~127,……,如果超出了上述范围,就会产生0号中断,而不是按照通常的想法使溢出标志OF置1.
3.Pentium指令系统中规定余数的符号和被除数的符号相同
4.除数运算后,标志位都是不确定的,都没有意义。

类型转换指令CBW/CWD/CWDE/CDQ

用于符号扩展,转换以后符号、数值大小和原来相同,目的是产生一个双倍长度的被除数,以适应除法运算的要求
CBW:将AL寄存器中的符号位扩展到AH中,从而将字节扩展成字
CWD:将AX中的符号位扩展到DX中,把字扩展成DX:AX中的双字
CWDE:将AX寄存器中的字扩展到EAX的高位称为双字
CDQ:将EAX中的双字扩展到EDX,称为EDX:EAX中的四字
Pentium的指令系统(3)——算术运算指令

BCD码指令AAA/DAA、AAS/DAS、AAM和AAD

BCD码:4位二进制码表示1个十进制吗,只有0~9共10个编码
BCD码分为两类:
1.组合:1个字节表示2位BCD码
2.非组合:1个字节只用低四位来表示BCD码,高4位为0

在对BCD码进行运算时,Pentium采用先对

(一)BCD码的加法十进制调整指令AAA/DAA
调整的过程会影响标志位
AAA:用于对两个非组合的BCD码相加结果进行调整,产生一个非组合的BCD码
DAA:用于对两个组合的BCD码相加结果进行调整
加法举例:
AX,BX中分别存放有用BCD码表示的4位十进制数,编写程序将两数相加(假设无十进制进位),结果存放于AX中
Pentium的指令系统(3)——算术运算指令
(二)BCD码的减法十进制调整指令AAS/DAS
AAS:非组合
DAS:组合

(三)BCD码的乘法十进制调整指令AAM
对BCD码数据进行乘法运算时,要求乘数和被乘数都用非组合的BCD码来表示,否则得到的结果将无法调整
Pentium的指令系统(3)——算术运算指令

注意:
1.AAM指令总是紧跟在乘法指令MUL之后,对两个非组合的BCD码相乘结果进行调整,最后得到一个正确的非组合的BCD码结果
2.BCD码总是作为无符号数看待
3.AAM指令影响标志位

(四)BCD码的除法十进制调整指令AAD
也使用非组合形式,且对BCD码运算的调整是在除法之前进行的,必须对除数和被除数都进行调整(调整为十六进制)

逻辑运算指令AND/OR/NOT/XOR/TEST

AND:与操作
OR:或
XOR:异或
都是双操作指令
Pentium的指令系统(3)——算术运算指令
作用:
1.AX中的16位数和1000H相与,结果放在AX中
2.EAX和EBX中的内容相与,结果放在EAX中
3.EDX和EBX+ESI所指单元开始的4个字节与,结果放在EDX中
4.AX和00F0H相或,结果在AX中
5.AL和0FH相异或,结果放在AL中
6.EAX与其本身进行异或,结果使EAX清零
7.ECX寄存器和立即数相异或
8.ECX与10000000H相异或,结果在ECX中

TEST:测试
此指令不仅执行AND指令的操作,而且把OF和CF标志清零,修改SF、ZF和PF标志。TEST指令不送回操作结果,而仅仅影响标志位,其操作数可为字节、字或双字。
Pentium的指令系统(3)——算术运算指令
作用:
1.如EAX的最高位为1,则ZF=0,否则ZF=1
2.如AL的最低位为1,则ZF=0,否则ZF=1

NOT:非
此指令的操作数只有一个,求出指令所给操作数的反码
Pentium的指令系统(3)——算术运算指令
1.AL中内容求反码,结果在AL中
2.EBX中内容求反码,结果在EBX中
3.1000H和1001H所指单元的内容求反,再送回

注意:
1.程序设计中,常用AND指令对指定位清0;
2.OR指令常用来对一些指定位置1;
3.NOT指令常用来将某个数据取反码,再加一,便可得到补码;
4.TEST指令用来检测指定位是1还是0;
5.NOT指令不影响标志位;AND、OR、XOR指令使OF和CF清0,并影响SF、ZF和PF标志;TEST影响ZF标志

移位指令SAL/SAR/SHL/SHR、ROL/ROR/RCL/RCR

(一)非循环移位指令SAL/SAR/SHL/SHR

Pentium的指令系统(3)——算术运算指令
(a)算术左移指令SAL:左移一次,最低位补零,最高位进入CF。在左移位数为1的情况下,移位后,如果最高位和CF不同,则溢出标志位OF置1,这样对有符号数来说,可以判断移位后的符号位和移位前的符号位不同。
(b)逻辑左移指令SHL:功能与SAL相同,因为对无符号数乘2和对有符号数乘2没有区别。
(c)算术右移指令SAR:执行时最高位保持不变,因为有符号数的最高位为符号位。
(d)逻辑右移指令SHR:执行时最高位补零。
Pentium的指令系统(3)——算术运算指令
作用:
1.将EDX中的值左移5位,最低位补0;
2.将EAX中的值左移若干位,CL中指出所移的位数,若CL中为4,则左移4位;
3.将AL左移1位,低位补0;

注意:
1.逻辑移位指令执行时,实际上是把操作数看成无符号数进行移位,所移,右移时最高位添0;算术移位指令执行时,则将操作数看成有符号数来进行移位,所移,右移时保持最高位的值不变
2.移位指令使用时,如果只移1~31位,那么指令中可直接指出移动位数,也可用CL寄存器指出;如果超过31位,则必须用CL寄存器指出
3.所有移位指令执行时,都会影响标志位CF、OF、PF、SF、ZF

(二)循环移位指令ROL/ROR/RCL/RCR
Pentium的指令系统(3)——算术运算指令
(a)不带CF的循环左移指令ROL
(b)不带CF的循环右移指令ROR
(c)带CF的循环左移指令RCL
(d)带CF的循环右移指令RCR

注意:
1.ROL和RCL指令在执行一次左移后,如果操作数的最高位和CF不等,则OF置1,可根据OF的值判断循环左移操作是否造成了溢出;
2.ROR和RCR指令在执行1位右移后,如果操作数的最高位和次高位不等,则表示移位后的数据符号和原来的符号不同了,此时也会使OF为1;