Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 指令长度可变时的指令解码_Assembly_Cpu Architecture_Microprocessors - Fatal编程技术网

Assembly 指令长度可变时的指令解码

Assembly 指令长度可变时的指令解码,assembly,cpu-architecture,microprocessors,Assembly,Cpu Architecture,Microprocessors,以下是一些说明及其相应的编码: 55 push %ebp 89 e5 mov %esp,%ebp 83 ec 18 sub $0x18,%esp a1 0c 9f 04 08 mov 0x8049f0c,%eax 85 c0 test %eax,%eax 74 12 je

以下是一些说明及其相应的编码:

55                      push   %ebp
89 e5                   mov    %esp,%ebp
83 ec 18                sub    $0x18,%esp
a1 0c 9f 04 08          mov    0x8049f0c,%eax
85 c0                   test   %eax,%eax
74 12                   je     80484b1 <frame_dummy+0x21>
b8 00 00 00 00          mov    $0x0,%eax
85 c0                   test   %eax,%eax
74 09                   je     80484b1 <frame_dummy+0x21>
c7 04 24 0c 9f 04 08    movl   $0x8049f0c,(%esp)
55推送百分比ebp
89 e5 mov%esp,%ebp
83 ec 18子$0x18,%esp
a1 0c 9f 04 08 mov 0x8049f0c,%eax
85 c0测试%eax,%eax
74 12 je 80484b1
b8 00 mov$0x0,%eax
85 c0测试%eax,%eax
74 09 je 80484b1
c7 04 24 0c 9f 04 08移动成本$0x8049f0c,(%esp)

今天的微处理器通常是32位或64位的,我猜它们通常以4字节或8字节的块从内存中读取数据。但是,指令可以具有可变长度。微处理器是如何解码这些指令的?为什么它们不是等长的,以便于实现?

我无法回答它们是如何解码的,但我可以回答为什么它们是可变长度的

可变长度的原因既有保持代码大小较小的愿望,也有不可预见的指令集扩展


减少指令大小

有些指令(本质上)需要更多的空间来编码。如果所有指令都设置为足够大的固定长度,以容纳这些指令,那么指令代码中将浪费大量空间。可变长度指令允许将指令“压缩”到更小的大小


(不可预见的)指令集扩展

另一个原因是指令集扩展。最初,x86只有256个操作码。(1字节)然后需要添加更多指令,因此他们抛出一条指令,并将其操作码用作新操作码的转义字符。结果是较新的指令更长。但这是扩展指令集并保持向后兼容性的唯一方法

至于处理器如何解码这些,这是一个复杂的过程。对于每条指令,处理器需要找到长度并从中解码。这导致固有的顺序解码过程,这是一个常见的性能瓶颈

现代x86处理器具有所谓的uop(micro-op)缓存,它将解码的指令缓存到处理器更易于管理(类似RISC)的内容中。

您已经重新发明了 嗯,您对经典x86的反对正是促使RISC CPU体系结构的设计者创建简单、一致、固定大小的指令集体系结构的原因

事实证明,如今的x86确实将用户可见的ISA转换成了一个更像RISC的微操作流,该微操作流位于内部缓存中

很好的观察



注释
1。微操作只是一种可用的技术。在一般情况下,只要指令的解码和对齐发生在一个或多个流水线级中,所花费的实际时间就不会添加到平均指令执行时间中。如果分支预测正在工作且管道保持满,则解码和对齐指令所需的额外时间将由与实际指令操作并行执行的逻辑处理。今天的设计师可以使用数百万门,他们可以用大量逻辑来解码复杂的x86 ISA。
2。您提到了内存总线宽度;事实证明,内存路径通常也大于32位或64位。架构字大小只是指ALU和指针大小。内存和缓存接口的实际宽度通常是体系结构字大小的2倍或4倍。

编辑:希望使其更具可读性

硬件不会将内存视为一长串无组织字节。所有处理器,固定或可变字长,都有特定的引导方法。通常是处理器内存/地址空间中的一个已知地址,具有引导代码的第一条指令的地址或第一条指令本身的地址。对于每个指令,当前指令的地址就是开始解码的位置

例如,对于x86,它必须查看第一个字节。根据该字节的解码情况,可能需要读取更多的操作码字节。如果指令需要地址、偏移量或其他某种形式的立即数,那么这些字节也存在。处理器很快就能准确地知道这条指令中有多少字节。如果解码显示该指令包含5个字节,并且从地址0x10开始,则下一条指令位于0x10+5或0x15。这将永远持续下去。无条件分支,根据处理器的不同,可以有不同的风格,您不能假设指令后面的字节是另一条指令。有条件或无条件的分支可以为您提供另一条指令或一系列指令在内存中的起始位置的线索

请注意,今天的X86在解码指令时肯定不会一次提取一个字节,会发生合理大小的读取,可能一次读取64位,处理器会根据需要从中提取字节。当从现代处理器读取单个字节时,内存总线仍会进行全尺寸读取,或者在总线上显示所有这些位,而内存控制器仅提取其所需的位,或者它可能会保留这些数据。您将看到一些处理器,其中在背靠背地址处可能有两个32位读取指令,但在内存接口上仅发生一个64位读取

我强烈建议您编写反汇编程序和/或模拟器。对于固定长度的指令,这是非常容易的,您只需从一开始就开始,并在遍历内存时进行解码。固定字长的反汇编程序可能有助于了解解码指令,这是该过程的一部分,但它无助于您理解以下可变字长指令以及如何在不脱离ali的情况下将它们分离