本文内容选自于北京大学陆俊林老师《计算机组成-x86指令简介》课程,非本文作者原创,仅为整理与总结。如有错误,烦请指出;如有需要,请在转载时附上本文链接。欢迎交流!
甲 指令的主要分类
根据执行结果的不同,x86的指令通常可分为下列几种:
1)运算类指令(如:四则运算、逻辑运算等)
2)传送类指令(如:从存储器到通用寄存器、从通用寄存器到I/O接口等)
3)控制类指令(如:暂停处理器、清除标志位等)
4)转移类指令(如:无条件转移、条件转移、过程调用等)
乙 常见指令
一 传送类指令
在这里,我们关注一个常用的传送类指令,即 MOV DST, SRC
这个指令的运行结果为,将寄存器SRC(通常称为源操作数)中的内容传送到DST(通常称为目的操作数)中。MOV指令的常见变形有如下几个:
1)MOV EBX, 40 直接给出操作数40;
2)MOV AL, BL 给出操作数所在的寄存器名称;
3)MOV ECX, [1000H] 给出存放操作数的存储器的地址;
4)MOV [DI], AX 给出存储操作数所在的寄存器地址的寄存器的名称;
5)MOV [BX + SI * 2 + 200H], 01H 给出计算存放操作数的寄存器地址的方法;
二 运算类指令
令DST,SRC分别为目的操作数与源操作数,OPR为操作数。
1)ADD DST, SRC
将SRC中的数据与DST中的数据进行加法,并将结果存储在DST中。该运算对进位标志CF(Carry flag)的结果有影响,若加法有进位,则CF = 1,反之CF = 0;
2)ADC DST, SRC
将SRC中的数据与DST中的数据进行有进位的加法,并将结果存储在DST中。ADC的结果 = ADD的结果 + CF的值;
3)INC OPR
将OPR进行加1操作,对CF无影响;
4)SUB DST, SRC
将SRC中的数据与DST中的数据进行减法,并将结果存入DST中。该运算对CF有影响。若减法出现借位,则CF = 1,反之CF = 0;
5)SBB DST, SRC
将SRC中的数据与DST中的数据进行有借位的减法,并将结果存储在DST中。SBB的结果 = SUB的结果 - CF的值;
6)DEC OPR
将OPR进行减1操作,对CF无影响。
注:
1)在设计INC和DEC操作时,x86的设计者将这两个运算用于对地址的增减,因此不涉及进位/借位运算。此外可用于不影响CF位值的算数用途的增减,而ADD/ADC/SUB/SBB则会影响CF位的值;
2)虽然ADD/ADC/SUB/SBB从功能上讲可以代替INC/DEC,但前者的机器码实现要长与后者,且后者出现频率也较高,所以这体现了x86为常见的运算设计较短指令从而达到节省有限的空间的设计理念。
*3)x86的标志位中包含进位标志、奇偶标志、半进位标志、零标志、符号标志、溢出标志、方向标志、中断标志和跟踪标志。
*三 转移指令
转移指令的作用是改变指令的执行顺序。根据是否存在判断条件,转移指令分为无条件指令与条件指令;根据转移目标地址的提供方式,可分为直接转移和间接转移。
如:JNZ LABEL 指令用于对零标志ZF(Zero flag)的值的判断。若ZF != 0,则程序跳转LABEL所指的指令,反之则不跳转。
*四 控制指令
控制指令的作用是实现对CPU功能的控制,该指令对标志位进行操作。
如:CLC指令将进位标志CF清零;CLD指令将方向标志DF清零;CLI将中断标志IF清零。
丙 实例
问题:计算存储器中分别起始于[2000H]和[3000H]的两个数之和,其中这两个数的长度存放在[2500H]字节单元中。
MOV CL, [2500H] ; 将2500H地址处的值移到CL寄存器中
MOV SI, 2000H ; 存储2000H起始的数
MOV DI, 3000H ; 存储3000H起始的数
CLC ; 在第一次循环前将进位标志CF清零
LOOP1: MOV AX, [SI]
ADC AX, [DI]
MOV [SI], AX
INC SI
INC SI
INC DI
INC DI
DEC CL
JNZ LOOP1 ; 当数长度为0时,停止循环
MOV AX, 0H
ADC AX, 0H ; 循环结束时,运算结果可能存在进位,所以对进位进行0 + CF的操作,取出进位
MOV [SI], AX
注:
上述代码中的INC指令不能用ADD替换,因为ADD会影响CF值,在循环累加的过程中被ADC误加导致结果错误。
丁 参考
北京大学《计算机组成》203-x86指令简介,计算机组成_北京大学_中国大学MOOC(慕课)