用实例学习:指令编码的解析!

这里,我尝试解析一些实际的指令编码:

(一)        指令Encode 转化为 汇编语句

以下指令编码摘自某句汇编码, 我将这段指令编码,解析成汇编语句:

示例一:
00000016:89 54 24 04
分析如下:
(1)        首先,看看Intel & AMD 的指令编码格式:(基本知识)
+--------+-----------------+-------------+-----------+-------+------------------+----------------+
| Prefix  |        REX prefix     |  OpCode  | Mod/RM | SIB    | Displacement  |  Immediate |
----------+-----------------+-------------+---------- +-------+-------------------+---------------+
   66           40                    1 byte     1 byte    1 byte    1,2,4 bytes    1,2,4 bytes
   67
   2E           |
   3E           |
   26
   64        althought
   65
   36           |
   F0           |
   F3
   F2          4F

REX prefix byte:仅仅被支持于:AMD64 处理器,目的是为了扩展64位Operands。
Intel的处理器没有该域。                         

Mod/RM bytes 由三个域组成:   XX       XXX        XXX   ( binary)
                                ——    ——     ——
                                mod     reg        r/m 

SIB bytes 同样由三个域组成:
XX      XXX       XXX (binary)
——    ——     ——
scale    index     base

(2) 第1个 byte :89 (Opcode),One byte encode。
通过查 Intel 或 AMD 手册得知这个Encode(编码)对应的指令是: Mov Ev, Gv
解释一下:这是一条mov 指令, 有两个Operand(操作数)。

目标Operand是:register 或者 memory operand,大小是 2 bytes 或 4 bytes,具体要根据指令的 default operand size 来定。本例中,这是一个 4 bytes 大小的数。

源Operand 是:register,大小为2 bytes 或 4 bytes。本例中是 4 bytes大小的数。

(3)        第2个byte:54 ( Mod/RM),One byte encode

54 (Mod / RM): 01       010      100
                             ——    ——      ——
                     |          |            |
                               +--------|------ --|----------------> mod (模式) : 01
                                           |           |
                                          +----------|----------------> register : 010  是 edx 寄存器
                                      |
                                                        +---------------> r/m ( memory reference):100

源Operand 是:edx 寄存器。
目标Operand: 在 mod 01 和 r/m 100 配合下,这是一个需要 [SIB] + displacement 的寻址模式,也就是说必须配合 SIB 字节才能正确寻址。故下1 bytes 必定是 SIB byte。

(4)        第3个bytes: 24 (SIB),One byte encode
24 (SIB):  00         100          100
                     ——      ——      ——
               |              |               |
                      +-----------|------------|------------------->  scale: 00
                                     +-----------|-------------------->  Index:  100 
                                                     +------------------->  Base :   100

scale: 00表示 scale 为 1
Index: 100表示 memory operand 的形式为 [base] 的形式
Base: 100表示 base register 为 esp 寄存器

现在,总结分析,目标operand是什么?
Mod/RM 表明:operand有一个 displacement 数
SIB     表明:  operand 的形式是 [base]

结合,Mod/RM 与 SIB 得出最终的Operand 寻址模式为:[base + displacement] 的寻址方式。
可得出结果为: [esp + disp]

(5) 最后一个 bytes:04 (displacement)

在SIB byte的下一个字节是 displacement(偏移量),这个偏移量是基于 code segmemt 的。
在这里是04 值。

总结:现在结果可以出来了,汇编形式为:
00000016:89 54 24 04            =>     movl  %edx,  4(%esp)

           例子二:

下面摘自某语句的编码,它的汇编形式是什么?
0f b6 4d f8 (hex)

(1)        首先,我们看第1个byte,是:0fh
byte 0F:说明这条指令的Opcode 有两个bytes
并且,这是一条32 bit 的operands 的指令。因为它没有prefix修饰码。

(2)        第2个byte,是:b6h,那么,我们查表(two-byte opcode表)得知:
这条指令是:MOVZX Gv,Eb
说明:这条指是带0扩展传送指令。这条指令的Opcode有2个bytes。
源Operand:Eb说明是1 byte的register或 memory数
目标Operand:Gv是任何一个General purpose register(通用寄存器),其大小是:word(2 bytes),doubleword(4 bytes)或者quadword(8 bytes)

(3)        第3个byte,是:4dh,这个byte是Mod/RM byte。也就是:01 001 101(binary)
得知:目标Operands是:ECX 寄存器。
源Operands的寻址方式是:[ebp] + displacement的形式。
而这个displacement只需要1个bytes,故,下一个byte 必定是displacement

(4)        第4个byte,是:f8h。
基于,第3点所述的,源operand的寻址方式是:[ebp]+displacement,它并不需要SIB byte。
故,这个字节是个displacement。
所以,源operands是:[ebp] + f8。

(5)        总结:结果是:
0f b6 4d f8 (hex)  =>  movzx ecx, byte ptr [ebp + f8] (Intel 格式)

转化我喜欢的AT&T格式为:movzbl 0xf8(%ebp), %ecx
                      即:movzbl  –8(%ebp), %ecx (最终结果)

            (二)将汇编语句解析为指令Encode(编码)

如下的语句,是如何转化为Encode的?

一、指令示例1:add  %ecx,%eax (AT&A格式)

(1)        查表,ADD Ev, Gv(Intel格式) 的Opcode Encode 是:01
(2)        operands encode 由 Mod/RM 决定。
分析如下:Ev 由 Mod/RM bytes中的 mod filed和 r/m filed 来决定
          Gv 由 Mod/RM bytes中的 reg filed 来决定。

故:Mod/RM byte 得出结果为:11 001 000(binary)  即:C8(hex)

总结: add  %ecx,  %eax   => 01 C8  (Instruction Encode)

二、指令示例2:add (%esp), %eax (AT&A格式)

(1)        查表得出:ADD Gv, Ev(Intel格式)的Opcode Encode是:03

(2)        同样地,Operands encode由Mod/RM决定,但是,这个例子中,源操作数的寻址方址是SIB形式,即:disp(base,index,scale) 的形式。故,光有Mod/RM byte是不够的,还必须结合SIB byte才行。
故,初步确定,这条指令需要3个bytes。包括:Opcode encode 、Mod/RM encode 以及 SIB encode。

(3)        GV 由 Mod/RM 中的 reg 域来决定。同时,Mod/RM 中的 r/m 域决定SIB 寻址。
故: Mod/RM 结果为:00 000 100 (binary),即:04(hex)

(4)        Ev 由最终由SIB来决定。SIB中的base 域决定哪个 base register。
SIB中的 Index 域决定寻址方式。
故:SIB 结果为: 00 100 100 (binary),即:24(hex)

(5)        最终结果编码为:
add  (%esp),%eax     =>    03 04 24 (Instruction Encode)   

三、指令示例3:
这里,我将AMD64的指令转化为Encodes
指令为:mov rax, [rbx](Intel格式,64位的操作数)

REX prefix 编码为:
          0100  X   X   X  X
               ——  —  — — —
            4    W   R  X  B  位

(1)        AMD 的REX prefix 设定了64-bit operands,故这条指令,必定需要REX prefix
REX的W位(第3 bit)作用是扩展64位操作数,此位置为1时,可以使用AMD的64-bit operand size。这里为1。
REX的B位(第0 bit)作用是扩展64寄存器。这里为1。
REX的R位(第2 bit)作用是扩展64寄存器。这里为1。
REX的X位(第1 bit)作用在SIB上,用于扩展寻址寄存器。这里为0。
故整个REX prefix 为:4D

(3)        查表得:MOV Gv, Ev 编码为:8B

(2)        Mod/RM byte为:03。这里并不需要SIB寻址方式
若:源操作数是[rbx + rcx]的情况下,就需要SIB字节了!因为,有了一个SIB寻址方式之故。

(3)        最终结果编码为:
mov rax,[rbx]          =>    4D 8B 03 (hex)

注意:这条指令必须是AMD64处理器,在被初始化64位模式下才能执行。
若:4D 8B 03 在IA32下执行会是:意想不到的结果!

希望我的分析能带给你一些帮助。当然,这里不可能很详细的讲解,其中Encode(编码)请查Intel 和 AMD 的手册,一些架构性的知识,也可以从指令中获得。

例如:

1、AMD为了支持64技术,在指令结构中引进了REX Prefixs。增加了8个通用寄存器(r8 – r15)。8个调试寄存器,8个控制寄存器。更有效地址的寻址方式

2、指令的default operad size 是32位的,在64-bit 模式中,AMD的REX Prefix 中的W(bit)扩充为64-bit。而 Prefix 66h 可以更改 Operand size 大小。Default address operands size 是64位的。Prefix 67h 可以更改Address operand size 的大小。

3、指令的缺省size由 CPU 当前的模式决定,若CPU 被初始化为64-bit 模式,则可以利用AMD64 技术。

4、通过,对指令编码的学习,可以开发自己的汇编语言编译器,从而最终实现自己的后端汇编器。实现64编译器。这就是我的目的!

posted on 2010-07-28 06:05  SunBo 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/sunyubo/archive/2010/07/28/2282142.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值