首页 文章

Linux x86 CPU指令布局混乱

提问于
浏览
1

在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

它看起来是指令mov eax,0x11223344编码为0x11 0x22 0x33 0x44 0xb8 .

问题 .

1.)如果看到的第一个字节不是操作码,CPU如何知道指令将占用多少字节?

2.)我想知道是否x86 cpu指令甚至没有endian-ness并且正在考虑某种类型的字符串? (可能离开这里)

1 回答

  • 5

    x86是一个可变长度的指令集,你从一个没有字节序的字节开始,它就在任何地方 .

    然后,取决于操作码,可能有更多的字节,例如可能是32位立即数,并且(如果该组字节是立即数或某种类型的地址),那么这些字节将是小端 . 假设您有五个字节ABCDE(没有endianess,认为数组或字符串) . A字节是操作码,B字节则是立即数的低8位,E是立即数的高8位 .

    操作码是一个难以使用的术语,在这些较旧的8/16位CISC处理器(如x86)中,整个字节是一个操作码,您基本上在表中查找它是什么意思(并且在处理器内部他们确实使用表格来计算)如何执行它) . 当您查看MIPS或ARM或其他(当然是RISC)指令集时,只有32位的一部分是“操作码”,并且在这两种情况下都不是从一条指令到另一条指令的相同位组,必须看一下指令中的各个地方(是的,有重叠使解码理智),MIPS更加一致,你在一个地方看到一个blob,但其中一个模式要求你看另一个blob位完全解码 . ARM你从一个共同的位开始,当你在你的工作中进一步解码指令,然后你可能必须 grab 一些随机观察点来完全解码 . 其余的位是操作数,要使用的寄存器或立即数,或者在CISC中需要查找表的任何类型(由操作码隐含但未由操作码中的位定义) .

    1)先前指令之后的下一个字节将被解释为操作码,即使不是一个操作码(如果执行继续到该字节并且不进行分支) . 我不记得我的x86表了解是否有任何未定义的指令,如果未定义则会触及处理程序,否则它将解码它发现的机器代码,如果它没有正确形成指令可能会崩溃,有时你会很幸运,它会让事情变得混乱,继续前进,甚至更加幸运,你不能说它几乎崩溃了 .

    2)你适合这些8/16位CISC或类似的指令集,它们被视为更像线性解析的字符串 .

相关问题