在C中编写ARM汇编模拟器时,我对此问题感到困惑。我在论坛中发现了一些类似的问题,但没有一个解释如何使用两个操作数之间的关系设置进位标志结果
任何回复都表示赞赏。提前谢谢。
方面。
答案 0 :(得分:6)
进位标志以正常方式设置,例如作为添加产生进位的结果。然后,您可以使用ADC
(with with carry)指令将此进位传播到高位字,例如在做64位时添加:
ADDS r4, r0, r2 ; add least significant words
ADC r5, r1, r3 ; add most significant words with carry
在此示例中,r4:r5中的64位值等于r0:r1和r2:r3中64位值的总和。
在早期版本的ARM上,你可以像这样设置进位标志 :
ORRS R15,R15,#&20000000
或者像这样:
TEQP R15,#&20000000
有关详细信息,请参阅本教程:http://www.peter-cockerell.net/aalp/html/ch-3.html
显然,较新版本的ARM已将进位标志移至另一个寄存器(请参阅下面的注释)。
答案 1 :(得分:4)
您必须检查处理器的参考手册,以了解哪些指令设置了进位标志以及使用哪种方式。我对ARM知之甚少,但我在其他处理器中看到了一些变化:
逻辑上生成进位的一些指令可能不会设置进位标志
某些指令可以使用进位标志作为一些额外的隐式操作数或结果而没有加/减的连接
减法后,处理器在进位标志设置的条件不同(即有些以与添加反转的第二个操作数后相同的方式进行,另一个将其设置为否定)< / p>
如果您想要的是一种方法来查看是否应该为C中的添加生成进位,这里有两种方式(第一种是直接定义,第二种来自无符号的环绕行为):
unsigned w1, w2, result;
int carry;
carry = w1 > UINT_MAX-w2;
result = w1 + w2;
carry = result < w1;
答案 2 :(得分:3)
查看你可以在gdb源代码中找到的装甲器。
对于两个操作数添加,您可以从操作数的msbits和结果判断是否有进位。或者你可以写一个实验性的8位加法器,并构建一个真值表。
编辑:
#include <stdio.h> #define BITS 2 #define MASK ((1<<BITS)-1) unsigned int ra,rb,rc; int main ( void ) { for(ra=0;ra<=MASK;ra++) { for(rb=0;rb<=MASK;rb++) { rc=ra+rb; printf("%u + %u = %u : %u %u %u : %u\n",ra,rb,rc,((ra>>(BITS-1))&1),((rb)>>(BITS-1))&1,((rc>>(BITS-1))&1),rc>>BITS); } } return(0); }
产生:
0 + 0 = 0 : 0 0 0 : 0 0 + 1 = 1 : 0 0 0 : 0 0 + 2 = 2 : 0 1 1 : 0 0 + 3 = 3 : 0 1 1 : 0 1 + 0 = 1 : 0 0 0 : 0 1 + 1 = 2 : 0 0 1 : 0 1 + 2 = 3 : 0 1 1 : 0 1 + 3 = 4 : 0 1 0 : 1 2 + 0 = 2 : 1 0 1 : 0 2 + 1 = 3 : 1 0 1 : 0 2 + 2 = 4 : 1 1 0 : 1 2 + 3 = 5 : 1 1 0 : 1 3 + 0 = 3 : 1 0 1 : 0 3 + 1 = 4 : 1 0 0 : 1 3 + 2 = 5 : 1 1 0 : 1 3 + 3 = 6 : 1 1 1 : 1
显而易见的情况是,当第一个操作数的msbit和第二个操作数的msbit被设置时,你将携带该位。两个不太明显的情况是当a的msbit被设置并且结果的msbit没有设置时,有一个进位,同样当b的msbit被设置并且结果的msbit没有被设置时,有一个进位
所以
carry=0 if((MSB(A))&&(MSB(B))) carry=1 if((MSB(A))&&(!MSB(ANS))) carry=1 if((MSB(B))&&(!MSB(ANS))) carry=1
答案 3 :(得分:3)
查看ARM Architecture Reference Manual(亲切地称为“ARM ARM”)。这些天你可能需要登录,但它们是免费的(仅仅是“承诺不起诉我们”的协议)。
ARM ARM具有关于何时以伪代码形式为每条指令设置和清除C位的详细信息。在ARMv5 ARM中,对于ADCS
,您有例如。
C Flag = CarryFrom(Rn + shifter_operand + C Flag)
...它们涵盖了ARM和Thumb指令集指令。
(你会注意到,几乎所有的算术Thumb模式指令都设置条件代码标志,包括进位位;除非它们设置了S标志,否则ARM模式指令大多数都没有。)
(另外,我的信息可能不是最新的;我最熟悉ARMv5TE架构。)