7. displacement 值
来源:互联网 发布:vr头显 知乎 定位 编辑:程序博客网 时间:2024/06/06 00:30
7. displacement 值
上一页 返回目录 下一页
displacement 是 ModRM 地址寻址里的一部分,displacement 为 base 或 index 提供一个 offset 值。
因此:在指令的编码中必须要提供 ModRM 字节,需要的时候还要提供 SIB 字节。
1、关于 displacement 的看法
(1)基于 ModRM 字节寻址的情况下,displacement 不是指令中的 immediate 部分
例如指令:mov edx, dword ptr [0x08040400]
它的指令编码是:8b 15 00 04 04 08
这条指令的 displacement 虽然是嵌在 encode 中,但它不属于 immediate 的概念,它是需要通过 ModRM.r/m 的寻址。
(2)有一种情况下,绝对地址不需要 ModRM 字节进行寻址,这个地址值是 immediate 部分
指令:mov eax, dword ptr [0x08040400]
它的指令编码可以译为:a1 00 04 04 08 (当绝对地址与 eax/rax 寄存器之间的寻址,它可以使用这种编码方式)
在这种情况下,它不需要 ModRM 字节进行寻址,这个地址值是 immediate 概念。
当然,这条指令也可以译为:8b 05 00 04 04 08 (通过 ModRM 进行寻址),此时它就是 displacement 部分。
2、提供 displacement 的几个方式
由 ModRM.mod 来控制 displacement:
(1)提供绝对地址方式
上表是提供绝对地址寻址的两种方式。表格中的 XX/XXX 表示可以为任意值。
注意方式 1 中,提供的 [disp32] 是在 非 64 位模式下。
(2)为 base 提供一个 offset 值
可以提供 8 位和 32 位的 displacement 值。
表格中的 XX/XXX 表示该项为任意值,8 位和 32 位的 displacemnet 各有 2 种编码方式。
(3)为 index 提供一个 offset 值
ModRM 配合 SIB 寻址,这里 SIB.index ≠100 时,提供任意的 index 寄存器(除了 rsp 寄存器),可以为 index 提供一个 32 位的 displacement 值。
仅在这一种情况下才允许 index + base 寻址。
看下面的指令:
mov rax, qword ptr [rcx * 8 + 0x0c]
它的 encode 是: 48 8b 04 cd 0c 00 00 00
它使用的 [base + index * 8] 寻址模式,在 SIB.base = 101(即:base = rbp) 的情况下,base 此时为 disp32
上面的有几种寻址方式,是依据 x32/x64 的两大原则,详见:ModRM 与 SIB 设计上的 2 个原则
(4)给 rip 提供一个 displacement 值
仅在 64 位模式下,可以为 rip 提供一个 displacement 值
当在 64 位模式下,ModRM = 00-XXX-101 是 [rip + disp32] 寻址,这是 x64 体系中新增的一个寻址模式。
这种寻址模式很容易就得出 rip 值,如下指令:
lea rax, [rip]
编译器会译出:8d 05 00 00 00 00 -----> lea rax, [rip + 0x00000000]
3、 displacement 的符号位
大部分情况下,displacement 是 signed(符号数),在绝对地址情况下,它是 unsigned(无符号数)
(1)displacement 是 signed(符号数)
无论是为 base 还 index 提供一个 offset 值,此时 displacement 都是 singed(符号数),那么将会按 singed 的计算方式,计算结果。
在这种情况下,当 displacement 是 disp8 时,它会被符号扩展到 address size(取决于 effective address size)
关于 effective address size 的详见:default(缺省)与 effective(有效)
(2) displacement 是 unsigned(无符号数)
当 displacement 是绝对地址是,它是 unsigned(无符号数)。
例如: mov edx, dword ptr [0x08040400] 此时 displacement 是一个 unsigned(无符号数)
4、displacement 的长度
在 16 位下 displacement 分为 8 位和 16 位,在 32 位下分为 8 位和 32 位,而在 64 位下同样只有 8 位和 32 位。
4.1、 displacement 的 signed-extended(符号扩展)
虽然有 8 位的 displacement,实际上,都会被 processor 进行 signed-extended 符号扩展到 address size
当 displacement size 是小于 address size 的,这个 displacement 就会被 singed-extended 到 address size
这个 address size 是指令当前的 address size,它取决于 effective address size。
★ 没有经过 address size override 的,address size 就是它的 default address size
★ 经过 address size override 后,address size 就等于 override 的 address size
关于 effective address size 的详见:default(缺省)与 effective(有效)
4.2、 x64 体系的 64 位下的 displacement
64 位的 default address size 是 64 位,在没有 address size override 的,无论 disp8 还是 disp32 都会被扩展到 64 位地址上。
这里就产生了一些疑问,在 x86/x64 的指令格式中,displacement 是没有 64 位的。
★ 到度有没有 64 位的 displacement 呢?
★ 没有的话,怎么使用 64 位绝对地址呢?
★ 有的话,什么情况下才会出现 64 位的 displacement 呢?
在 x64 体系的的编码中,确实没有 64 位 displacement 这回事,但是并不表示 64 位下不能使用 64 位的绝对地址。 这个 64 位的绝对地址并不是 displacement 的意思。
例子: mov rax, qword ptr [0xffff800008040400]
这条指令是正确的,而且它使用了 64 位的绝对地址。
它的 encode 是:48 a1 00 04 04 08 00 08 ff ff
这条指令的 Opcode 是 a1,指令形式为:MOV rAX, Ov
second operand 是 O 表示它将是一个直接的地址形式,这个 operand 是允许使用 64 位的绝对地址,而不需要 ModRM 寻址。
在这里地址值 [0xffff800008040400] 它是以 immedeate 值形式嵌在 encode 中,它属于 immediate 部分,而非 displacement 值。
同样,指令:mov qword ptr [0xffff800008040400], rax 也是正确的
它的 encode 是:48 a3 00 04 04 08 00 08 ff ff
另一个例子是:mov rcx, qword ptr [0xffff800008040400]
这条指令是错误的,它不可能产生 encode,opcode a1 是仅仅对 rax 寄存器可用,因此:只有 rax 寄存器才能使用 64 位的绝对地址值。
4.3、 Opcode a1 和 a3 可以使用 64 位绝对地址的本质
这两个 Opcode 的 operand 嵌入 encode 中,它不依赖于 ModRM 寻址。 在这种情况下,可以设计使用 64 位的地址值(immediate)。
因此:
设计使用 64 位地址的前提条件必须是: operand 不依赖于 ModRM 寻址,换句说说:operand 是嵌在 Opcode 里的。
4.4、 不能使用 64 位 displacement 的本质
我们来看一看,是什么原因限制了 64 位 displacement 的使用。
例子: mov qword ptr [rax + rcx * 8 + 0x11223344], 0x12345678
这个例子是前面多次提到过,它的 encode 是:48 c7 84 c8 44 33 22 11 78 56 34 12 (共 12 个 bytes)
可以看出,限制 64 位 displacement 使用的原因就是:指令长度的限制
由于 x86/x64 的指令长度限制 15 bytes, 如果上面这条指令可以使用 64 位 displacement 的话,指令长度超过了 15 bytes。
因此:
使用 64 位 displacement 第 2 个前提条件是:指令长度不能超过 15 bytes
4.5、 operand 类型为 O (直接地址值,不依赖于 ModRM 寻址)的最终设计前提就是前面所说的两个条件:
★ operand 不依赖于 ModRM 寻址,换句说说:operand 是嵌在 Opcode 里的。
★ 指令长度不能超过 15 bytes
那么:能不能为 x64 体系扩展指令格式为更长的格式呢?
显然,x64 体系设计者们没有采取这种方式,出于兼容的大提前下,是不可能有这种考虑的。
上一页 返回目录 下一页
mik(deng zhi)写于 2008-11-26 15:40
- 7. displacement 值
- X86指令编码内幕 --- displacement 值
- Displacement Activity
- Displacement Map
- Displacement map water wave
- 移位贴图 Displacement Mapping
- PC-relative with displacement
- 移位贴图 Displacement Mapping
- Displacement Mapping (Direct3D 9)
- displacement map置换贴图
- Half Life2 Displacement Terrain System
- Bump / Normal / Displacement / Parallax Mapping
- Displacement Mapping(移位贴图)
- Tessellation(曲面细分)和Displacement Mapping
- 3DShader之移位贴图(Displacement Mapping)
- Tessellation (曲面细分) Displacement Mapping (贴图置换)
- 第九章 Normal Mapping and Displacement Mapping
- Using Vertex Texture Displacement for Realistic Water Rendering(上)
- 5. ModRM 寻址模式
- 6. SIB 补充寻址
- 这些工作真的适合我吗?
- C和指针读书笔记——快速上手
- 堆和栈的区别-两种不同的数据结构
- 7. displacement 值
- 8. immediate 值
- 9. 指令解析
- Android 用户界面---操作栏(Action Bar 一)
- Android 用户界面---操作栏(Action Bar 二)
- Android 用户界面---操作栏(Action Bar 三)
- Android TextView中文字设置超链接、颜色、字体
- 未定义变量报错
- android4.0访问第三方的sharedPreferences数据