我有多个非常小的问题在大会上,这也是相关的,所以我收集他们在这个问题上,而不是打开多个论坛和垃圾邮件。
所有问题都与程序集At&t语法有关:
cmp %eax,$0x2jg goHere
为什么不允许进行比较操作(结果没有保存在一个操作数中,所以不允许它.)注意:我知道我可以通过倒序来解决这个问题,然后做jl
而不是jg
。
在att语法中,应该检查0x2是否大于%eax。
mov $41 %rax
虽然我不能写:
mov (41美元),%rax
这很奇怪,有人告诉我,在装配中使用支架并不重要。
0x100 -A 0x101 -B 0x102 -C
0x100-C0x101-B0x102-A
发布于 2021-10-05 14:08:23
对于1,我对x86的最初设计没有特别的了解,但我怀疑我们没有cmp %reg, $imm
的原因是因为cmp
和sub
之间的关系。指令cmp $imm, %reg
的行为与sub $imm, %reg
完全一样,只有一个例外,即对于cmp
,减法的结果不是写入目标%reg
,而是被丢弃。但是减法的结果仍然是由CPU在内部计算,并用于设置标志。(至少这在概念上是正确的,而且早期CPU几乎肯定完成了全部减法;现代CPU可能有一些我不知道的优化。)
因此,这意味着一旦您拥有了cmp
,几乎可以免费实现sub
。你可以使用几乎完全相同的电路和/或微码。但是您仍然需要对指令进行解码,因此,通过给cmp
提供几乎与sub
相同的编码,这也很容易,只需一位就不同了。例如,sub %reg, %reg/mem
是操作码28h/29h,cmp %reg, %reg/mem
是操作码38h/39h,仅在第4位有不同之处。这一位只是指示CPU是将结果写到目标操作数还是丢弃它。
这使得给cmp
提供与sub
完全相同的表单变得很自然。
cmp %reg, %reg
.
sub %reg, %reg
所以有sub %reg, %reg
cmp %reg, mem
.
sub %reg, mem
所以有sub %reg, mem
cmp mem, %reg
.
sub mem, %reg
所以有sub mem, %reg
cmp $imm, %reg
.
sub $imm, %reg
所以有sub $imm, %reg
sub $imm, %al/%ax/%eax/%rax
短编码,它有一个并行的但是没有sub %reg, $imm
编码,因为这将是胡说八道,所以cmp %reg, $imm
需要一种新的编码,而这种编码不会与sub
现有的编码并行。设计者大概决定不把解码晶体管和操作码空间浪费在创建晶体管和操作码空间上,因为毕竟它并没有真正提供任何新功能:cmp
实际上总是与条件跳转(或后来的条件集)一起使用,在这种情况下,您可以通过使用cmp $imm, %reg
并在随后的条件跳转/集中逆转测试来实现相同的目标。
https://stackoverflow.com/questions/69446758
复制相似问题