购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

1.3.1 指令代码格式

指令代码格式(Instruction Code Format)说明如何用二进制编码指令,也称机器代码(Machine Code)格式。指令由操作码和操作数(地址码)组成。指令的操作码(Opcode)表明处理器执行的操作,例如,数据传送、加法运算、跳转等操作。操作数(Operand)是参与操作的数据,也就是各种操作的对象,主要以寄存器或存储器地址、I/O地址形式指明数据的来源,所以也称为地址码。例如,数据传送指令的源地址和目的地址,加法指令的加数、被加数及和值都是操作数。有些指令不需要操作数,通常的指令都有1个或2个操作数,也有个别指令有3个甚至4个操作数。多数操作数需要显式指明,有些操作数隐含使用。

IA-32处理器的指令系统采用可变长度指令格式,指令编码非常复杂。这一方面是为了兼容8086指令,另一方面是为了向编译程序提供更有效的指令。图1-7是IA-32处理器指令代码的一般格式。它包括几个部分:可选的指令前缀、1~3字节的主要操作码、可选的寻址方式域(包括ModR/M和SIB字段)、可选的位移量和可选的立即数。指令前缀和主要操作码字段对应指令的操作码部分,其他字段对应指令的操作数部分。

图1-7 IA-32处理器指令代码的一般格式

1.指令前缀

指令前缀(Prefix)是指令之前的辅助指令(也称前缀指令),用于扩展指令功能。每个指令之前可以有0~4个前缀指令,顺序任意,并可以分成4组。

第1组包括LOCK前缀指令(指令代码为F0H),用于控制处理器总线产生锁定操作。使用LOCK前缀后,在指令的执行过程中,不允许其他处理器访问共享存储器中的数据,从而保证了数据的唯一性。第1组中还包括仅用于串操作指令的重复前缀指令REP、REPE/REPZ、REPNE/REPNZ,用于控制串操作指令的重复执行。

第2组主要是段超越(Segment Override)前缀指令,用于明确指定数据所在段。它们是CS、DS、SS、ES、FS、GS,对应的指令代码依次是2EH、3EH、36H、26H、64H、65H。

第3组是操作数长度超越(Operand-size Override)前缀,指令代码为66H。第4组是地址长度超越(Address-size Override)前缀,指令代码为67H。某条指令单独或同时使用了操作数长度超越前缀和地址长度超越前缀,将改变默认的长度。

保护方式下,IA-32处理器可以通过段描述符为当前运行的代码段选择默认的地址和操作数长度:32位地址和操作数长度或者16位地址和操作数长度。使用32位地址长度,最大偏移地址是FFFFFFFFH(2 32 -1),逻辑地址由一个16位段选择器和一个32位偏移地址组成。使用16位地址长度,最大偏移地址是FFFFH(2 16 -1),逻辑地址由一个16位段选择器和一个16位偏移地址组成。32位操作数长度确定操作数可以是8位或者32位;16位操作数长度确定操作数可以是8位或者16位。例如,当前段默认是32位操作数长度和地址长度,而如果指令使用了操作数长度超越前缀,则指令的操作数实际上是16位。

实地址方式、虚拟8086方式、系统管理方式默认采用16位地址和操作数长度,也可以使用两个长度超越前缀,以采用32位操作数和地址长度。不过,此时采用32位地址长度所访问的线性地址最大是000FFFFFH(2 20 -1)。

2.操作码和操作数

指令执行的操作(如加、减、传送等)编码称为操作码部分。主要操作码是1~3个字节,有些还用到ModR/M中的3位。

IA-32处理器有多种存取操作数的方法,所以操作数的编码(地址码)也比较复杂。寻址方式的ModR/M和SIB字段提供操作数地址信息。例如,它们指明操作数是在指令代码中还是在寄存器或存储器中。如果操作数在指令代码中,立即数字段就是所需要的操作数;如果操作数在存储器中,则需要进一步指明采用何种方式访问存储器,有时还需要相对起始地址的位移量。

IA-32处理器除上述一般指令格式外,还有一些特殊的编码格式。有关指令代码的详细编码组合已经超出本书的范围,具体可以阅读参考文献。下面以程序中使用最多的同时也是指令系统中最基本的数据传送指令为例进行简单说明。

数据传送指令的助记符是MOV(取自Move),其功能是将数据从一个位置传送到另一个位置,类似于高级语言的赋值语句。对于如下所示的语句:

SRC表示要传送的数据或数据所在的位置,称为源(Source)操作数,写在逗号之后。DEST表示数据将要传送到的位置,称为目的(Destination)操作数,写在逗号之前。

例如,将寄存器EBX的数据传送到EAX寄存器的指令可以书写为:

这个指令的机器代码是8B C3(十六进制)。其中,8B表示操作码,C3表示操作数。如果使用16位操作数形式,即指令“MOV AX,BX”,那么它的机器代码是66 8B C3,这里的66就是操作数长度超越前缀。

再如,将由EBX指明偏移地址的存储器内的数据传送到EAX,可以书写为:

这个指令的机器代码是8B 03(十六进制)。其中,03字节由ModR/M字段生成。

如果数据不在默认的DS数据段,则需要使用段超越前缀显式说明。例如:

该指令用“ES:”表示数据在ES段,它的机器代码是26 8B 03,这里的26就是ES段超越前缀。

IA-32支持复杂的数据寻址方法,例如:

这个指令中,数据来自主存数据段,偏移地址由ESI内容乘以4加EBX再加位移量80H组成。它的机器代码是8B 84 B3 80 00 00 00。其中84由ModR/M字段生成,B3由SIB字段生成,后面4个字节表达位移量00000080H。 Jwmg1gugcItdW7gakRO9AG5nurnbYULoycRuyKsU3Cf2n05QHfGQXDQjr9gDh6lF

点击中间区域
呼出菜单
上一章
目录
下一章
×