Viz*_*ary 7 x86-64 intel cpu-word machine-code endianness
尽管单词的常见定义(如维基百科所述)是:
用于指定存储器中的位置的最大可能地址大小通常是硬件字(这里,“硬件字”是指处理器的全尺寸自然字,而不是使用的任何其他定义)。
根据一些消息来源,x86 系统注意到它被视为 16 位:
在 x86 PC(Intel、AMD 等)中,虽然架构很早就支持 32 位和 64 位寄存器,但其本机字大小可以追溯到 16 位起源,“单个”字为 16 位。“双”字是 32 位。请参阅 32 位计算机和 64 位计算机。
然而英特尔的官方文档(sdm 第 2 卷,第 1.3.1 节)指出:
这意味着字的字节从最低有效字节开始编号。图 1-1 说明了这些约定。
图 1-1 显示了 x86-64 上下文中单词的小端序列中的 4 个字节,而不是 2 个字节或 8 个字节(如上面链接的来源的不同定义所建议的那样):
我对这一切真正感到困惑的是如何获取和解析指令。我正在编写一个模拟器,一旦我解析 PE 格式的可执行文件并进入文本部分,如果我要遵循 4 字节小端格式,这是否意味着将首先解析第 4 个字节?
让我们组成一些字节,例如:
.text segment buffer:
< 0x10, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20 > ....
Run Code Online (Sandbox Code Playgroud)
我会将第一条指令解析为 1C、1B、1A、10、20、1F、1E、1D ...(等等,由于长度可变,显然可能有更多的单词需要读取,具体取决于这里的实际字节是什么)?
不,x86机器码是字节流;除了 32 位位移和小尾数立即数之外,它没有任何面向字的内容。例如在add qword [rdi + 0x1234], 0xaabbccdd. 它在现代 CPU 上以 16 字节或 32 字节块的形式物理获取,并在指令边界上并行分割以并行馈送到解码器。
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
Run Code Online (Sandbox Code Playgroud)
x86-64不是面向字的架构;不存在单一的自然字长,并且事物不必对齐。当考虑 x86-64 时,这个概念并不是很有用。整数寄存器宽度恰好是 8 字节,但这甚至不是机器代码中的默认操作数大小,您可以在大多数指令中使用从字节到 qword 的任何操作数大小,对于 SIMD,可以使用 8 或 16 字节到 32 字节或 64 字节。最重要的是,机器代码甚至数据都不需要更宽整数的对齐。
有些人喜欢将方钉插入圆孔并用机器字来描述 x86,但这个概念只适合围绕单个字大小设计的 RISC ISA。(对于某些 RISC 上的字大小访问,固定指令长度、寄存器大小,甚至数据存储器加载/存储都需要字对齐,尽管现代的 RISC 通常允许未对齐的加载/存储,但会带来一些性能损失。)
(公平地说,64 位 RISC 通常对 32 位和 64 位整数也同样有效。但与 x86 不同的是,它们无法避免将add ax, cx进位传播到寄存器的较高位。尽管 RISC 可以执行 16 位对符号扩展或零扩展加载结果进行一些数学运算后存储)。
有关的:
根据一些来源,请注意它被视为 16 位:
是的,在 x86 术语/文档中,一个“字”是 16 位,因为现代 x86-64 是从 8086 演变而来的,当 386 还存在时,改变每个人多年来一直使用的文档中术语的含义是愚蠢的。释放。因此,paddw16 位 SIMD 元素的压缩加法,以及movsw/stosw/etc。字符串指令。
x86 16位“字”与CPU架构中“机器字”的概念绝对零联系。
在 8086 到 286 上,16 位是寄存器和总线宽度,也是除字节之外唯一可用于大多数 ALU 指令的整数操作数大小。但这些 CPU 仍然不像 MIPS 那样基于“文字”;机器代码格式仍然相同,具有未对齐的小端 16 位立即数和位移。(8088 与 8086 相同,除了 8 位总线接口和 4 字节指令预取缓冲区而不是 6 字节。)
| 归档时间: |
|
| 查看次数: |
1187 次 |
| 最近记录: |