cpu指令如何工作?

时间:2014-03-26 21:58:59

标签: c++ assembly vm-implementation

据我所知,在32位处理器中,每条指令都是32位。那么,对于汇编中的MOV指令,如何仅将32位用于操作码加参数?所以:

MOV register, [address]

地址本身是否占用32位?那么这不会占用整个指令吗? 也许我错了,但我正在尝试用C / C ++实现一个VM。帮助

7 个答案:

答案 0 :(得分:6)

x86指令的长度可变。 CPU以第一个字节开始读取指令,识别“操作码”,然后根据实际指令继续读取后续字节。

我在随机点停止了调试器(Visual Studio),它的反汇编窗口有一个选项“Show Code Bytes”,它给出了一个指令长度的例子。看看下面:

enter image description here

特别要看一下mov [ebp-15Ch], eax中与你问题中提到的一致的内容。相应的字节包括A4 FE FF FF,它是-15Ch的32位值。

答案 1 :(得分:5)

实际上,操作码可以是可变长度或固定长度,具体取决于架构。还有16位和32位处理器,带有20位地址总线。 这些天架构位宽度不是很清楚。它更像历史事物。我想最好的"定义"这些天可能是"逻辑"的宽度。内部数据总线。 (请记住8088:具有8位多路复用数据总线的16位器件。)

答案 2 :(得分:4)

某些处理器(如x86)通过使用可变长度指令解决了这个问题,因此指令不是32位长 - x86有一些长度为单字节的指令,而有些指令超过10个字节。 (这也意味着指令并不总是在32位边界上对齐,显然)。

其他处理器通过“两部分常量加载”来解决它,例如ARM,MIPS和29K具有将“低部分”和“高部分”加载为单独实体的指令(通常,加载低部分清除或签名 - 扩展上部,高部分保持低部分不变,这样,可以在单个指令中加载小值)。

当然,很多时候,我们不是处理常量地址,而是使用保存地址的变量(也就是指针或引用),在这种情况下,“加载”指令从一个地址加载在寄存器中,而不是一个恒定的值。

答案 3 :(得分:3)

在像ARMv7这样严格为32位的汇编程序中,不能在单个指令中存储操作码和绝对地址。你要做的就是

  1. 将地址从内存加载到寄存器中,然后跳转到寄存器中的地址。
  2. 存储相对于程序计数器[pc]
  3. 的地址

    ARM体系结构手册可以为此提供帮助。

答案 4 :(得分:3)

这里有很好的答案解释指令格式。然而似乎没有人澄清你的混淆:在32位架构上,指令操作数的长度是32位(*),而不是指令。指令由操作代码[和操作数]组成(并非所有指令都有操作数,例如nopsti)。

(*)无论什么规则,这都不适用于。例如,32位x86架构有一个指令集扩展(SSE),它需要128位甚至256位操作数。

答案 5 :(得分:2)

Risc处理器,如arm,具有固定大小的指令。 X86是一个cisc处理器(可变大小指令)。对于risc处理器,32位地址分为2部分(16位 - hi和low),并通过执行2个加载指令加载到一个寄存器中,然后我们可以加载(mov)地址的内容另一个注册。因此,最多可能需要3条指令才能将内容从内存中移入寄存器。

答案 6 :(得分:-1)

CPU不与OS“通信”。 CPU就是电路。指令解码电路基于与从存储器读取的指令位的模式匹配来激活其他电路。

它们都是标准化的,因此相同的操作系统可以在任何x86 CPU上运行,例如。

但是,32位CPU的处理速度低于64位CPU。 CPU可以分为单元,然后可以像存储器IC一样进行访问。

如果您不支持团队,那么为您的硬件编写软件仍然很困难。