|
|
1
4
您必须查看参考手册,让处理器知道哪些指令设置了进位标志,以及以何种方式设置。我对ARM的了解还不够,但我在其他处理器上看到了一些变化:
如果您想要的是查看是否应该为C中的加法生成进位的方法,这里有两种方法(第一种方法是直接从定义开始,第二种方法来自无符号的环绕行为):
|
|
|
2
6
进位标志以正常方式设置,例如,由于产生进位的加法。然后您可以使用
在本例中,r4:r5中的64位值等于r0:r1和r2:r3中的64位值之和。 在ARM的早期版本中,您可以设置进位标志 明确地 这样地:
或者像这样:
有关详细信息,请参阅本教程: http://www.peter-cockerell.net/aalp/html/ch-3.html 显然,ARM的新版本将进位标志移到了另一个寄存器(见下面的注释)。 |
|
|
3
3
退房 ARM Architecture Reference Manual (亲切地称为“手臂”)。这些天你可能需要登录,但他们是免费的(只是在“承诺不起诉我们”协议之后)。
ARM具有关于何时为每个伪代码形式的指令设置和清除C位的详细信息。在armv5臂中,用于
…它们涵盖了手臂和拇指指令集指令。 (您将注意到,几乎所有的算术拇指模式指令都设置了条件代码标志,包括进位始终;ARM模式的指令通常不设置,除非设置了S标志。) (另外,我的信息可能不是最新的;我最熟悉ARMV5TE体系结构。) |
|
|
4
3
看看你可以在gdb源中找到的armulator。 对于双操作数加法,可以从操作数的最高位和有进位的结果中分辨出来。也可以编写一个实验性的say 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 显而易见的情况是,当设置第一个操作数的最高位和第二个操作数的最高位时,您将把该位带过来。不太明显的两种情况是,当设置了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 |
|
|
Daniel · 仅在-O3中进行未对齐的内存访问 2 年前 |
|
|
TRElec · STM32:代码的执行似乎取决于它在闪存中的位置 2 年前 |
|
|
Marietto · FATAL:ThreadManitizer:不支持的VMA范围FATAL:找到39-支持的48/go:添加了github.com/docker/docker v23.0.4+不兼容 3 年前 |
|
|
Ilya Loskutov · 无法将单词加载到寄存器中 4 年前 |