- 1、本文档共50页,可阅读全部内容。
- 2、有哪些信誉好的足球投注网站(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。
- 3、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 4、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
查看更多
x86x64指令系统思考.
解开 x86/x64 指令编码中的迷惑1. 解开 x86/x64 指令长度的迷惑在 《x86/x64 指令编码内幕之指令格式》 一文,见 /x64/format.html 中说过:指令长度为 15 bytes 那么事实上是这样吗?谁来保证指令的长度就是 15 bytes? 怎样来保证?现在,我们来探索这个问题。?1.1 理论上确实有明文规定没错, AMD manual Vol3 第 1.1 Instruction Byte Brder 节中明确地说:An instruction can be between one and 15 bytes in length.而 Intel manual 上没有明说指令长度是多少,而下图的描述有些让人迷惑: prefix 最多可以是 4 bytesopcode 最多可以是 3 bytesmodrm 是 1 bytesib 是 1 bytedisplacement 是 4 bytesimmediate 是 4 bytes 这样的描述,让人直觉认为 在饱和状态下 最多可以是 17 bytes, 事实上有可能会达到这样的饱和状态吗? 要达到这样的饱和状态,必须每个部分都要饱和事实上这是不可能 每个部分同时达到饱和状态 的。事实上最长的指令长度会出现在:prefix 达到饱和,ModRM/SIB 达到饱和, displacement 达到饱和,immediate 达到饱和。而这些饱和不可能与 opcode 同时发生饱和。只有 指令 memory,immediate 这种寻址模式下才有这些饱和状态出现,即:目标操作数是 memory,源操作数是 immediate事实上:??? opcode 在 2 bytes 和 3 bytes 下,不可能有饱和的 immediate 出现。也就是说: 没有 4 bytes 的 immediate 会出现在2 bytes 或 3 bytes 的 opcode。指令集设计时候要遵循这个原则即:指令 memory, immediate 这种寻址模式不会出现在 2 bytes 或 3 bytes 的 opcode 指令中 ? 1.2 还是那个例子lock add dword ptr es:[eax+ecx*8+0, 0仅在 16 位模式下,这条汇编语句的 encode 是 15 bytes 因为:它在 16 位模式下,需要进行 operand size override 和 address size override,因此能达到 prefix 的饱和 从而每个部分除了 opcode 外,都达到了饱和状态。刚刚好是 15 bytes:26 66 67 F0 81 84 C8 44 33 22 11 78 56 34 12 4 group 的 prefix 都使用上了,ModRM 和 SIB 都需要,displacement 和 immediate 都是 4 bytes 的,只有 opocde 是 1 byte这条指令在 32 位是:26 F0 81 84 C8 44 33 22 11 78 56 34 12 (13 bytes)在 64 位下:26 67 F0 81 84 C8 44 33 22 11 78 56 34 12 (14 bytes) 那是因为 32 位下缺省的 operands size 和 address size 是 32 位,不需要作 operand size override 和 address size override 在 64 位下缺省的 operands size 是 32 位,而 address size 是 64 位,因此不需要作 operand size override,但是需要做address size override?上面的论述可以解开我们心中的迷惑了吗?不能! 下面继续...?1.3 总会有不守规则的现象出现我们还存在疑惑,是因为:总有不守规则的现象出现。貌似这个才是真理 :) 编译器总是循规蹈矩的,它一定会按指令编码规则来生成规矩的 encode,除非编译器有 bug。因此:不要期待编译器会产生不守规则的现象这个不守规则的现象是人为生产的。1.3.1 测试 nasm 中的 ndisasm 反汇编下面是 ndisasm 的输出 26 2E 3E 66 67 F0 81 84 C8 44 33 22 11 78 56 34 12? lock add dword [dword ds:eax+ecx*8+0,0disasm 反汇编出这条指令居然有 17 bytes!没错,多出来的 2 bytes 是我人为加上去的!而不是编译器产生的。但
文档评论(0)