尽管单词的常见定义(如维基百科所述)是:
用于指定存储器中的位置的最大可能地址大小通常是硬件字(这里,“硬件字”是指处理器的全尺寸自然字,而不是使用的任何其他定义)。
根据一些消息来源,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中,我理解多字节对象存储在内存中的小端样式.
现在一般来说,当谈到CPU指令时,OPCODE确定指令的目的,数据/存储器地址可以遵循其编码格式的操作码.我的理解是指令的操作码部分应该是最重要的字节,因此出现在任何给定指令编码表示的最高地址.
有人可以解释这个x86 linux gdb示例中的内存布局吗?我认为操作码0xb8会出现在更高的地址,因为它是最重要的字节.
(gdb) disassemble _start
Dump of assembler code for function _start:
0x08048080 <+0>: mov eax,0x11223344
(gdb) x/1xb _start+0
0x8048080 <_start>: 0xb8
(gdb) x/1xb _start+1
0x8048081 <_start+1>: 0x44
(gdb) x/1xb _start+2
0x8048082 <_start+2>: 0x33
(gdb) x/1xb _start+3
0x8048083 <_start+3>: 0x22
(gdb) x/1xb _start+4
0x8048084 <_start+4>: 0x11
Run Code Online (Sandbox Code Playgroud)
它看起来是指令mov eax,0x11223344编码为0x11 0x22 0x33 0x44 0xb8.
问题.
1.)如果看到的第一个字节不是操作码,CPU如何知道指令将占用多少字节?
2.)我想知道是否x86 cpu指令甚至没有endian-ness并且正在考虑某种类型的字符串?(可能离开这里)