CPU指令系统

来源:互联网 发布:专业视频剪辑软件iii 编辑:程序博客网 时间:2024/05/21 08:51

指令系统确定了CPU所能完成的功能,是用汇编语言进行程序设计的最基本部分。

1、指令格式

汇编语言的指令格式如下:

指令助忆符 [操作数1 [, 操作数2 [, 操作数3]]] [;注释]

指令助忆符体现该指令的功能,它对应一条二进制编码的机器指令。

指令的操作数个数由该指令的确定,可以没有操作数,也可以有一个、二个或三个操作数。绝大多数指令的操作数要显式的写出来,但也有指令的操作数是隐含的,不需要在指令中写出。

当指令含有操作数,并要求在指令中显式地写出来时,则在书写时必须遵守:

①指令助忆符和操作数之间要有分隔符,分隔符可以是若干个空格或TAB键;

②如果指令含有多个操作数,那么,操作数之间要用逗号","分开。

2、指令系统

2.1、数据传送指令

2.1.1、MOV

功能是把源操作数(第二操作数)的值传给目的操作数(第一操作数)。指令执行后,目的操作数的值被改变,而源操作数的值不变。

其格式为:MOV  Reg/Mem, Reg/Mem/Imm

其中:Reg—Register(寄存器),Mem—Memory(存储器),Imm—Immediate(立即数),它们可以是8位、16位或32位(特别指出其位数的除外)。

截图01

相关规定:

①两个操作数的数据类型要相同,要同为8位、16位或32位;如:MOV  BL, AX等是不正确的;

两个操作数不能同时为段寄存器,如:MOV  ES, DS等;

③代码段寄存器CS不能为目的操作数,但可作为源操作数,如:指令MOV  CS, AX等不正确,但指令MOV  AX, CS等是正确的;

立即数不能直接传给段寄存器,如:MOV  DS, 100H等;

⑤立即数不能作为目的操作数,如:MOV  100H, AX等;

⑥指令指针IP,不能作为MOV指令的操作数;

两个操作数不能同时为存储单元,如:MOV  VARA, VARB等,其中VARA和VARB是同数据类型的内存变量。

对于规定2、4和7,我们可以用通用寄存器作为中转来达到最终目的。

2.1.2、传送—填充指令

传送—填充指令是把位数短的源操作数传送给位数长的目的操作数。

指令格式如下:

MOVSX/MOVZX  Reg/Mem, Reg/Mem/Imm ;80386+

MOVSX为符号填充:用源操作数的符号位来填充目的操作数的高位数据位

MOVZX为零填充:恒用0来填充目的操作数的高位数据位。

2.1.3、交换指令XCHG

交换指令XCHG是两个寄存器,寄存器和内存变量之间内容的交换指令,两个操作数的数据类型要相同。

其指令格式如下:

XCHG  Reg/Mem, Reg/Mem

注意:寄存器不能是段寄存器,两个操作数也不能同时为内存变量。

2.1.4、取有效地址指令LEA

把一个内存变量的有效地址送给指定的寄存器。

其指令格式如下:

LEA Reg, Mem

该指令通常用来对指针或变址寄存器BX、DI或SI等置初值之用。

截图01 

2.1.5、取段寄存器指令

该组指令的功能是把内存单元的一个“低字”传送给指令中指定的16位寄存器,把随后的一个“高字”传给相应的段寄存器(DS、ES、FS、GS和SS)。

其指令格式如下:

LDS/LES/LFS/LGS/LSS Reg, Mem

注意:若Reg是16位寄存器,那么,Men必须是32位指针;若Reg是32位寄存器,那么,Men必须是48位指针,其低32位给指令中指定的寄存器,高16位给指令中的段寄存器。指令的执行结果如图5.5所示。

截图01

2.1.6、堆栈操作指令

主要有两大类操作:进栈操作和出栈操作。

①进栈操作:PUSH(Push Word or Doubleword onto Stack)

指令格式:

PUSH Reg/Mem

其中:

一个字进栈,系统自动完成两步操作:SP←SP-2,(SP)←操作数;

一个双字进栈,系统自动完成两步操作:ESP←ESP-4,(ESP)←操作数。

②出栈操作

指令格式:

POP Reg/Mem

其中:

弹出一个字,系统自动完成两步操作:操作数←(SP),SP←SP+2;

弹出一个双字,系统自动完成两步操作:操作数←(ESP),ESP←ESP+4。

2.2、标志位操作指令

标志位操作指令是一组对标志位置位、复位、保存和恢复等操作的指令。

①进位CF操作指令

清进位指令CLC(Clear Carry Flag):CF←0

置进位指令STC(Set Carry Flag):CF←1

进位取反指令CMC(Complement Carry Flag):CF←not CF

②方向位DF操作指令

清方向位指令CLD(Clear Direction Flag):DF←0

置方向位指令STD(Set Direction Flag):DF←1

③中断允许位IF操作指令

清中断允许位指令CLI(Clear Interrupt Flag):IF←0
其功能是不允许可屏蔽的外部中断来中断其后程序段的执行。

置中断允许位指令STI(Set Interrupt Flag):IF←1
其功能是恢复可屏蔽的外部中断的中断响应功能,通常是与CLI成对使用的。

④取标志位操作指令

LAHF(Load AH from Flags):AH←Flags的低8位

SAHF(Store AH in Flags):Flags的低8位←AH

⑤标志位堆栈操作指令

PUSHF/PUSHFD(Push Flags onto Stack):把16位/32位标志寄存器进栈;

POPF/POPFD(Pop Flags off Stack):把16位/32位标志寄存器出栈;

2.3、算术运算指令

2.3.1、加法指令

①加法指令ADD

指令的格式:ADD  Reg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数的值加到目的操作数中。

②带进位加指令ADC

指令的格式:ADC  Reg/Mem, Reg/Mem/Imm
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是把源操作数和进位标志位CF的值(0/1)一起加到目的操作数中。

③加1指令INC

指令的格式:INC  Reg/Mem
受影响的标志位:AF、OF、PF、SF和ZF,不影响CF
指令的功能是把操作数的值加1。

④交换加指令XADD

指令的格式:XADD  Reg/Mem, Reg ;80486+
受影响的标志位:AF、CF、OF、PF、SF和ZF
指令的功能是先交换两个操作数的值,再进行算术“加”法操作。

例子:

已知有二个32位数d1和d2(用数据类型DD说明),编写程序片段把d2的值加到d1中。

截图01

方法1:用16位寄存器编写程序

MOV AX, word ptr d1      ;由于d1是双字类型,必须使用强制类型说明符。以下同。

MOV DX, word ptr d1+2 ;(DX,AX)构成一个32位数据

ADD AX, word ptr d2      ;低字相加

ADC DX, word ptr d2+2  ;高字相加。在低字相加时,有可能会产生“进位”

MOV word ptr d1, AX      ;低字送给d1的低字

MOV word ptr d1+2, DX  ;高字送给d1的高字

方法2:用32位寄存器编写程序

MOV EAX, d1

ADD EAX, d2

MOV d1, EAX

2.3.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-操作数,即改变操作数的正负号。

例子:

已知有二个32位数d1和d2,编写程序片段从d1中减去d2的值。

方法1:用16位寄存器编写程序

MOV AX, word ptr d1     ;取低字

MOV DX, word ptr d1+2 ;取高字,(DX,AX)构成一个32位数据

SUB AX, word ptr d2      ;低字相减

SBB DX, word ptr d2+2  ;高字相减。在低字相减时,有可能会产生“借位”

MOV word ptr d1, AX     ;低字送给d1的低字

MOV word ptr d1+2, DX ;高字送给d1的高字

方法2:用32位寄存器编写程序

MOV EAX, d1

SUB EAX, d2

MOV d1, EAX

2.3.3、乘法指令

计算机的乘法指令分为无符号乘法指令和有符号乘法指令,它们的唯一区别就在于:数据的最高位是作为“数值”参与运算,还是作为“符号位”参与运算

乘法指令的被乘数都是隐含操作数,乘数在指令中显式地写出来。CPU会根据乘数是8位、16位,还是32位操作数,来自动选用被乘数:AL、AX或EAX

指令的功能是把显式操作数和隐含操作数相乘,并把乘积存入相应的寄存器中。

截图01

①无符号数乘法指令MUL(Unsigned Multiply Instruction)

指令的格式:MUL  Reg/Mem
受影响的标志位:CF和OF(AF、PF、SF和ZF无定义)
指令的功能是把显式操作数和隐含操作数(都作为无符号数)相乘,所得的乘积按表5.2的对应关系存放。

②有符号数乘法指令IMUL(Signed Integer Multiply Instruction)

指令的格式:
IMUL Reg/Mem        ;把显式操作数和隐含操作数相乘,所得的乘积按表5.2的对应关系存放。

IMUL Reg, Imm         ; 其寄存器必须是16位/32位通用寄存器,其计算方式为:Reg ← Reg × Imm

IMUL Reg, Reg, Imm  ;其寄存器只能是16位通用寄存器,其计算方式为:Reg1 ← Reg2×Imm  或  Reg1 ← Mem×Imm

IMUL Reg, Reg/Mem  ;其寄存器必须是16位/32位通用寄存器,其计算方式为:Reg1 ← Reg1×Reg2  或  Reg1 ← Reg1×Mem

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

在指令格式2~4中,各操作数的位数要一致。如果乘积超过目标寄存器所能存储的范围,则系统将置溢出标志OF为1。

2.3.4、除法指令

除法指令的被除数是隐含操作数,除数在指令中显式地写出来。CPU会根据除数是8位、16位,还是32位,来自动选用被除数AX、DX-AX,还是EDX-EAX。

除法指令功能是用显式操作数去除隐含操作数,可得到商和余数。当除数为0,或商超出数据类型所能表示的范围时,系统会自动产生0号中断。

无符号数除法指令DIV(Unsigned Divide Instruction)

指令的格式:DIV  Reg/Mem
指令的功能是用显式操作数去除隐含操作数(都作为无符号数),所得商和余数按表5.3的对应关系存放。指令对标志位的影响无定义。

有符号数除法指令IDIV(Signed Integer Divide Instruction)

指令的格式:IDIV  Reg/Mem
受影响的标志位:AF、CF、OF、PF、SF和ZF

指令的功能是用显式操作数去除隐含操作数(都作为有符号数),所得商和余数的对应关系见表5.3。

截图01

原创粉丝点击