在 Intel x86-64 架构上是否以小端 4 字节字获取机器代码指令? [英] Are machine code instructions fetched in little endian 4-byte words on an Intel x86-64 architecture?

查看:28
本文介绍了在 Intel x86-64 架构上是否以小端 4 字节字获取机器代码指令?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尽管词的常见定义(

我对这一切的真正困惑在于指令是如何获取和解析的.我正在编写一个模拟器,一旦我解析了一个 PE 格式的可执行文件并进入了文本部分,如果我要遵循 4 字节小端格式,这是否意味着将首先解析第 4 个字节?

让我们组成一些字节,例如:

.text 段缓冲区:<0x10, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 >....

我是否会将第一条指令解析为 1C, 1B, 1A, 10, 20, 1F, 1E, 1D ...(依此类推,由于长度可变,显然可能有更多的单词需要阅读取决于这里的实际字节数)?

解决方案

不,x86 机器码是一个 字节流;除了小端的 32 位位移和立即数外,它没有任何面向字的内容.例如在 添加 qword [rdi + 0x1234], 0xaabbccdd.它在现代 CPU 上以 16 字节或 32 字节的块进行物理提取,并在指令边界上并行拆分以并行提供给解码器.

48 81 87 34 12 00 00 dd cc bb aaREX.W 添加 ModRM le32 0x1234 le32 0xaabbccdd le32(符号扩展到 64 位)添加 QWORD PTR [rdi+0x1234],0xffffffffaabbccdd

x86-64 不是面向字的架构;没有单一的自然字长,也不必对齐.在考虑 x86-64 时,这个概念不是很有用.整数寄存器宽度恰好是 8 字节,但这甚至不是机器代码中的默认操作数大小,并且您可以使用从字节到 qword 的任何操作数大小与大多数指令,以及从 8 或 16 字节到 32 的 SIMD或 64 字节.最重要的是,机器代码甚至数据不需要更宽整数的对齐.


有些人喜欢将方钉装入圆孔中,并用机器字来描述 x86,但这种概念仅适用于围绕单个字大小设计的 RISC ISA.(对于某些 RISC 上的字大小访问,固定指令长度、寄存器大小甚至数据存储器加载/存储都需要字对齐,尽管现代的通常允许未对齐的加载/存储会带来一些性能损失.)

(公平地说,64 位 RISC 通常对于 32 位和 64 位整数也同样有效.但与 x86 不同的是,它们不能执行 add ax, cx 避免将进位传播到寄存器的较高位.尽管 RISC 可以在对符号扩展或零扩展加载结果进行一些数学运算后进行 16 位存储).

相关:


<块引用>

根据某些来源,请注意它被视为 16 位:

是的,在 x86 术语/文档中,词"是指是 16 位,因为现代 x86-64 是从 8086 演变而来的,在 386 发布时改变每个人已经使用多年的文档中术语的含义是愚蠢的.因此 paddw 打包添加了 16 位 SIMD 元素movsw/stosw/等.字符串指令.

一个 x86 16 位字"与机器词"的概念绝对零联系;在 CPU 架构中.

在 8086 到 286 上,16 位是寄存器和总线宽度,并且是大多数 ALU 指令可以使用的除字节之外的唯一整数操作数大小.但是那些 CPU 仍然非常不基于文字".MIPS的方式;机器代码格式仍然相同,具有未对齐的小端 16 位立即数和位移.(8088 与 8086 相同,除了 8 位总线接口和 4 字节指令预取缓冲区而不是 6 字节.)

Despite a common definition for word (as stated on Wikipedia) being:

The largest possible address size, used to designate a location in memory, is typically a hardware word (here, "hardware word" means the full-sized natural word of the processor, as opposed to any other definition used).

x86 systems, according to some sources, note it's treated as 16 bits:

In the x86 PC (Intel, AMD, etc.), although the architecture has long supported 32-bit and 64-bit registers, its native word size stems back to its 16-bit origins, and a "single" word is 16 bits. A "double" word is 32 bits. See 32-bit computer and 64-bit computer.

Yet Intel's official documentation (sdm vol 2, section 1.3.1) states:

this means the bytes of a word are numbered starting from the least significant byte. Figure 1-1 illustrates these conventions.

and Figure 1-1 shows 4 bytes in little endian sequence, not 2 bytes or 8 bytes (as the varying definition by sources linked above would suggest) of word in the x86-64 context:

And where my confusion really lies about all this is how instructions are fetched and parsed. I'm writing an emulator and once I parse a PE formatted executable and get to the text section, if I'm to follow the 4-byte little endian format, doesn't that mean the 4th byte would be parsed first?

Let's make up some bytes for example:

.text segment buffer:
< 0x10, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 > ....

Would I parse the first instruction as 1C, 1B, 1A, 10, 20, 1F, 1E, 1D ... (and so on, being variable length there's obviously potentially more words to read depending on what the real bytes are here)?

解决方案

No, x86 machine code is a byte-stream; there's nothing word-oriented about it, except for 32-bit displacements and immediates which are little-endian. e.g. in add qword [rdi + 0x1234], 0xaabbccdd. It's physically fetched in 16-byte or 32-byte chunks on modern CPUs, and split on instruction boundaries in parallel to feed to decoders in parallel.

48    81   87     34 12 00 00    dd cc bb aa       
REX.W add ModRM    le32 0x1234    le32 0xaabbccdd le32 (sign-extended to 64-bit)

   add    QWORD PTR [rdi+0x1234],0xffffffffaabbccdd

x86-64 is not a word-oriented architecture; there is no single natural word-size, and things don't have to be aligned. That concept is not very useful when thinking about x86-64. The integer register width happens to be 8 bytes, but that's not even the default operand-size in machine code, and you can use any operand-size from byte to qword with most instructions, and for SIMD from 8 or 16 byte up to 32 or 64 byte. And most importantly, alignment of wider integers isn't required in machine code, or even for data.


Some people like to fit a square peg into a round hole and describe x86 in terms of machine-words, but that concept only really fits well for RISC ISAs that are designed around a single word size. (Fixed instruction length, register size, and even data memory load/store is required to be word aligned for word-sized accesses on some RISCs, although modern ones often allow unaligned load/store with some performance penalty.)

(To be fair, 64-bit RISCs are usually also equally efficient with 32 and 64-bit integers. But unlike x86 they can't do add ax, cx that avoids propagating carry into the higher bits of a register. Although RISCs can do a 16-bit store after some math on sign-extending or zero-extending load results).

Related:


according to some sources, note it's treated as 16 bits:

Yes, in x86 terminology / documentation, a "word" is 16 bits, because modern x86-64 evolved out of 8086 and it would have been silly to change the meaning of a term in the documentation everyone had been using for years when 386 was released. Hence paddw packed add of 16-bit SIMD elements, and movsw/stosw/etc. string instructions.

An x86 16-bit "word" has absolutely zero connection to the concept of a "machine word" in CPU architecture.

On 8086 through 286, 16-bit was the register and bus width, and the only integer operand-size other than byte you can use for most ALU instructions. But those CPUs were still very much not based around "words" the way MIPS is; The machine-code format was still the same, with unaligned little-endian 16-bit immediates and displacements. (8088 was identical to 8086, except for the 8-bit bus-interface and 4-byte instruction prefetch buffer instead of 6-byte.)

这篇关于在 Intel x86-64 架构上是否以小端 4 字节字获取机器代码指令?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆