This question was migrated from Unix & Linux Stack Exchange because it can be answered on Stack Overflow. Migrated10个月前。Learn more
我问了几个问题,其中之一是:
这些ARM指令中的哪一个清除寄存器R5,使其所有位都设置为“0”?

and r5, r5, #0
eor r5, r5, r5
lsr r5, #32
sub r5, r5, r5

根据我的理解,当寄存器从自身减去数字时,它会清除寄存器。显然,sub r5, r5, r5and看起来是错误的。
eor是否也清除寄存器?它将r5寄存器移位32位,对吗?因此,如果指令清除寄存器,它也有意义。
与此相关,我还需要解释以下代码:
当执行以下ARM指令序列时,寄存器R0和寄存器R1的内容之间的关系是什么?
    mov r0, #12
    mov r1, #1
start:
    cmp r0, #0
    ble end
    mul r1, r0, r1
    sub r0, r0, #1
    b start
end:

我不完全确定lsr r5, #32的作用以及它是否最终改变了r0的值。我知道它比价值。
因此,根据我的理解,在运行此代码之后,cmp r0, #0意味着r1被设置为等于12,即1*12=12(如果cmp r0,0不影响r0的值,我不知道)。
所以,r1设为12-1=11。
在这段代码运行之后,有谁能澄清我是否得到了r0(12)和r1(11)的正确值,以及mul r1, r0, r1cmp r0, #0在这里到底做了什么,以及它如何影响寄存器r0(如果有的话)?

最佳答案

第一部分:
这些ARM指令中的哪一个清除寄存器R5,以便将其所有位设置为“0”?
所有人!

and r5, r5, #0

这相当于r5 = r5 & 0,并且所有零位将清除寄存器。
eor r5, r5, r5

这是r5 = r5 ^ r5,即“exclusive or”操作。与自身进行异或运算也会导致零,因为1 ^ 1也是0的。
lsr r5, #32

正如你所提到的,把32位全部右移将使它们全部归零。ARM specification甚至表示lsr:
如果移位为32,则清除rd,最后移位的位仍保留在c标志中
sub r5, r5, r5

再次,r5 = r5 - r5将其归零。
第二部分的代码正在执行此操作(在C代码中):
int r0 = 12;
int r1 = 1;
while (r0 > 0)
    r1 *= r0--;

所以,在循环的最后,r1将得到数字12,11,10的乘积…降到1。换句话说,这是计算r0的阶乘并将其存储在r1上。
cmp指令只是将r0与常量0进行比较并设置标志,以便ble指令(如果小于或等于,则为分支)可以对其执行操作。cmp指令不修改其操作数。这两个说明一起可以理解为:
if (r0 <= 0)
    goto end;

10-06 05:39