汇编指令二进制代码介绍材料.doc
《汇编指令二进制代码介绍材料.doc》由会员分享,可在线阅读,更多相关《汇编指令二进制代码介绍材料.doc(58页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、.汇编指令与二进制代码对应手册汇编指令与二进制代码具有一一对应关系,也就是说,一条汇编指令必将唯一对应一条二进制代码指令,而一条二进制代码指令也唯一对应一条汇编指令,这就为写一个汇编语言与二进制指令相互对应的参考表成为可能。手册的使用范围本手册的读者需要据有一定的计算机专业知识,了解CPU的工作原理及内部的体系结构,熟悉IBM汇编、NASM或其它汇编语言,并且对汇编语言指令的二进制代码有足够的兴趣。本手册列出了绝大部分的中文汇编指令与二进制指令的对应关系,及相应的英文汇编指令名称。由于作者水平有限,而且本手册主要是对照NASM汇编语言指令集、Intel 微处理器结构、编程与接口中文第六版及其I
2、ntel公司公布的IA-32 Intel Architecture Software Developers Manual2001年版的PDF格式文档指令集而生成的,或许有一些比较新的指令或者其他CPU特有的指令,并未收集在本手册中。汇编指令解析一、操作码 汇编指令按其功能可分为:一般指令、浮点指令、多媒体指令和SIMD流式扩展(SSE)指令。汇编指令因其繁多且对应的二进制代码有多种变化而变得异常复杂,二进制代码的指令都是由操作码与操作数构成,就指令与操作数的关系而言,指令无非是无操作数、单操作数、双操作数和三操作数。所谓的操作码就是唯一代表着指令的意义的一段二进制码,操作码可以是单字节或者是双
3、字节。有一种特殊的操作码,它与操作数合起来共用一个字节或者两个字节,这种操作码的操作数都是寄存器,而且寄存器的二进制代码都为这操作码字节的最后三位,在参照表中用“操作数指令”字段表示,如果这个段中的数据为“是”就表示这个操作码是与寄存器操作数共用一个字节或两个字节,否则就不是。从对照表中,我们可以看出,实事上二进制操作码与汇编指令名称并非一一对应,一条汇编指令的名称如:转移指令,它可以对应多个操作码,只有当指令名称与指令操作数合在一起,才与操作码和操作数有一一对应的关系。也就是说同一个指令名称,指令操作数类型不同,对应的二进制操作码也可能不同。操作码在对照表是用“操作码”字段表示。在操作码字节
4、中通常又有方向位、符号位、操作数大小修饰位值得注意,它们都用一个二进制位来表示,方向位与符号位通常都在操作码的倒数第二位,而操作数修饰位通常在操作码的最后一位。举例说明:如果倒数第二位是方向位,那么如果这一位值为0,那么表示操作数是从左到右,如果是1表示操作数从右到左;如果倒数第二位是表示符号位,那么如果这一位值为0表示操作数是无符号操作数,如果值为1表示操作数为有符号操作数;如果最后一位是修饰操作数位,那么最后一位为0表示操作数是八位操作数,就是字节操作数,最后一位为1表示操作数大小由汇编模式决定,如果是16位汇编就表示是16位操作数,即字操作数,如果是32位汇编就表示是32位操作数,即双字
5、操作数。汇编模式是16位还是32位,由汇编代码决定,在NASM汇编中默认为32位模式,如果代码显示地给出BIT16就表示汇编成16位模式,如果代码显示地给出BIT32就表示汇编成32位模式。汇编模式不同,操作数也不相同,具体请看操作数节中介绍。二、操作数 计算机指令之所以复杂的一个主要原因就是操作数有多种变化,最为简单的指令就是无操作数指令。其中操作数可以是立即数、寄存器和内存地址。通常情况下,操作数含有立即数的指令与不含立即数的指令,指令操作码不同;操作数都为寄存器的,通用寄存器、段寄存器、控制寄存器、调试寄存器和任务寄存器的指令操作码不同;多媒体指令、浮点指令和SIMD指令都有各自的指令系
6、统。最为复杂的变化是当操作数为寄存器或内存的时候,之所以把它们放在一起,是因为它们都由一个叫做模数(MOD)的两位二进制数来决定。计算机指令是如何分辨多变的操作数的呢?前面提到,如果操作数是立即数,那么就用操作码来区分。当操作数是寄存器或是内存地址时,主要是用一个字节来区分,这个字节的前两位就是模数(MOD),后三位是寄存器的二进制代码,最后三位的值由开始两位的模数来决定具体的类型,如果模数为11那么最后三位就用来表示寄存器。内存地址是用寄存器的值来表示的,有的内存地址带有位移量,于是,当模数为00时字节的最后三位就表示寄存器内的数据是内存地址,并且没有位移量,当模数为01时,字节最后三位表示
7、寄存器内的数据是内存地址,并且在这一字节之后有8位数的位移量,当模数为10时字节后面有16位或32位,是16位还是32位由汇编模式来决定。16位模式常用于实模式,可使用16位寄存器,如AX、BX等,32位常用于保护模式,可使用32位寄存器,如EAX、EBX等。然而,只用一个字节的最后三位来表示内存地址,不可能用来表示众多的寄存器组合,于是模数为00时(没有位移量),就有在16位汇编模式,当nnn=000(nnn表示是用来表示内存的三位二进制数)时,内存地址为DS:BX+SI,在32位汇编模式时nnn=000,内存地址为DS:EAX,其它的值请参照后面的对应表。于是,我们知道了,计算机指令是通过
8、模数、寄存器和寄/内三个域来决定操作数的,其实除此之外,还有一种特殊的情况,就是操作数并没有都用到这三个域,而是把第二个域的值设为一个预设值,也就是说,第二个用来表示寄存器的域设成了固定值,而不是可变的寄存器,那么这就出现了只有一个寄存器或是内存地址操作数的变型,其实它是由前一种类型变化得来的。有三个操作数的指令又是如何的呢?实事上搞明白了上一种变化,三个操作数就很容易了,它只不过是在两个寄存器或内存地址操作数之后再加一个立即数,这种情况同样有一种特例,那就是有两个相同寄存器操作数,和一个立即数,那么在写汇编代码的时候就把这种情况认为是一个寄存器和一个立即数,而实际翻译成二进制代码时要翻译成两
9、个相同的寄存器和一个立即数,它同样是属于三个操作数的情况,IMUL指令就属于这一种特例。在具体的指令中还有一些例外,比如,一个看上去只有一个操作码,不含操作数的指令,而实际上它有隐含的寄存器作为它的操作数如计数寄存器,或者它的寄存器操作数被指令指定了,而不是可变的,如只使用累加寄存器,这也是比较常见的,这些在对照表中有详细的注明。三、指令前缀 有些指令通过添加前缀来改变默认段或超越指令模式。所谓超越指令模式是指在16位汇编模式时使用了32位的寄存器或者由32位寄存器组成的内存地址,或者在32位汇编模式时使用了16位寄存器或者由16位寄存器组成的内存地址。当使用超越前缀时,应把前缀字节放在指令的
10、面前,有多个前缀时前缀字节没有顺序地排列。超越前缀表前缀字节 作用26H ES:段超越前缀2EH CS:段超越前缀36H SS:段超越前缀3EH DS:段超越前缀64H FS:段超越前缀65H GS:段超越前缀2EH 分支未获取前缀(原英文是:Branch not taken,分支暗示前缀-仅用于条件跳转(Jcc)指令)3EH 分支被获取前缀(原英文是:Branch taken,分支暗示前缀-仅用于条件跳转(Jcc)指令)66H 对操作数长度的指令模式超越67H 对内存地址长度的指令模式超越F0H 锁(LOCK)指令前缀F2H 不相等重复/不为零重复前缀(REPNE/REPNZ)指令前缀(只适
11、用于字符串操作指令)F3H 重复(REP)指令前缀(只适用于字符串操作指令)F3H 相等重复/为零重复前缀(REP/REP)指令前缀(只适用于字符串操作指令)四、总结 通过以上的分析,我们可以总结出计算机指令的结构,由于286以前(含286)的处理器只能识别16位地址指令,且不能识别超越前缀字节,因此,这种16位地址指令的格式又与32位地址,即386以后(含386)的处理器的指令格式有所不同,如下表: 16位计算机指令格式(适用于286以前的处理器) 操作码操作数0x带模数的寄存器和寄/内操作数内存位移量立即数1-2字节0-1字节0-2字节0-2字节32位计算机指令格式(适用于386以后的处理
12、器)指令超越前缀操作码操作数0x66/0x670x带模数的寄存器和寄/内操作数比例变址*内存位移量立即数由前缀个数而定1-2字节0-1字节0-1字节0-4字节0-4字节*值得注意的是,操作数域中的比例变址只适用于32位寻址方式,且此时jjj/nnn=100 比例变址字节的前两位表示比例因子,后三位表示变址寄存器,最后三位表示基地寄存器,最终得到的地址值是:比例因子*变址+基址,当比例因子为00时乘以1,当比例因子为01是乘以2,当比例因子为10时乘以4,当比例因子为11时乘以8。其中“带模数的寄存器和寄/内操作数”这一操作数域仅占一个字节,如下表示:mm jjj jjj/nnn mm是两位模数
13、 jjj是三位表示的寄存器 nnn是三位用寄存器的值来表示的内地地址当mm=11时 jjj/nnn的值就表示为寄存器,即:11 jjj jjj当mm=00时 jjj/nnn的值就表示为内存地址,即:00 jjj nnn 且此时“内存位移量”域不取值,没有位移量当mm=01时 jjj/nnn的值就表示为内存地址,即:01 jjj nnn 且此时“内存位移量”域取8位的位移量当mm=10时 jjj/nnn的值就表示为内存地址,即:10 jjj nnn 且此时“内存位移量”域取16位或32位的位移量,如果是16位汇编模式则取16位的位移量,如果是32位汇编模式则取32位的位移量。是否有最后面的立即数
14、操作数则由操作码来决定。如果汇编代码指定为16位汇编模式,但指令的操作数中使用了32位的寄存器,则就需要在指令前加0x66的超越前缀,如果是使用了32位寄存器的值来表示内存地址,则需要在指令前加0x67的超越前缀,同理,汇编代码指定为32位汇编模式时,在指令的操作数中使用了16位的寄存器,也需要在指令前加0x66的超越前缀,如果是使用了16位寄存器的值来表示内存地址,则需要在指令前加0x67的超越前缀。其每条指令的这两种超越前缀已经在指令对照表中完整给出。寄存器中文-英文命名对照表类型中文名称英文名称二进制码寄存器说明多 功 能 寄 存 器累加低八AL000累加寄存器低八位累加高八AH100累
15、加寄存器低八位累加16AX00016位累加寄存器累加32EAX00032位累加寄存器基址低八BL011基址寄存器低八位基址高八BH111基址寄存器低八位基址16BX01116位基址寄存器基址32EBX01132位基址寄存器计数低八CL001计数寄存器低八位计数高八CH101计数寄存器低八位计数16CX00116位计数寄存器计数32ECX00132位计数寄存器数据低八DL010数据寄存器低八位数据高八DH110数据寄存器低八位数据16DX01016位数据寄存器数据32EDX01032位数据寄存器类型中文名称英文名称二进制码寄存器说明指针寄存器堆栈指针16SP10016位堆栈指针寄存器堆栈指针32
16、ESP10032位堆栈指针寄存器基址指针16BP10116位基址指针寄存器基址指针32EBP10132位基址指针寄存器变址寄存器目标变址16DI11116位目标变址寄存器目标变址32EDI11132位目标变址寄存器源变址16SI11016位源变址寄存器源变址32ESI11032位源变址寄存器专用寄存器指令指针16IP*16位指令指针寄存器指令指针32EIP*32位指令指针寄存器标志16FLAGS*16位标志寄存器标志32EFLAGS*32位标志寄存器段寄存器代码段CS001代码段寄存器数据段DS011数据段寄存器附加段ES000附加段寄存器堆栈段SS010堆栈段寄存器标志段FS100标志段寄存
17、器全局段GS101全局段寄存器控制寄存器控制零CR0000控制寄存器零控制一CR1*001控制寄存器一控制二CR2010控制寄存器二控制三CR3011控制寄存器三控制四CR4100控制寄存器四控制五CR5*101控制寄存器五控制六CR6*110控制寄存器六控制七CR7*111控制寄存器七调试寄存器调试零DR0000调试寄存器零调试一DR1001调试寄存器一调试二DR2010调试寄存器二调试三DR3011调试寄存器三调试四DR4*100调试寄存器四调试五DR5*101调试寄存器五调试六DR6110调试寄存器六调试七DR7111调试寄存器七任务寄存器任务零TR0000任务寄存器零任务一TR1001
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编 指令 二进制 代码 介绍 材料
限制150内