新手ARM汇编程序问题。我正在编写我的第一个arm汇编程序,我正在尝试编写这个C片段。
int x = somevalue1 << 12; // s19.12
int y = somevalue2 << 12; // s19.12
int a = somevalue3 << 12; // s19.12
int b = somevalue4 << 12; // s19.12
int c = somevalue4 << 12; // s19.12
long long acc = (long long) a * b;
acc += (long long) x * y;
int res = (acc >> 24);
acc += (long long) c * a;
我编写了第一部分并计算了r10,r11寄存器中的和。
@ r6 =a, r4 = b, r0 = x,r2 =y, r3=c
smull r10, r11, r6, r4 @acc = a * b
smlal r10, r11, r0, r2 @acc += x * y
现在我需要通过将“long long”右移24位来从r10和r11寄存器中提取“res”的值。我该怎么做?
-Thanks,
答案 0 :(得分:3)
r10包含低32位,r11包含高32位。
r10 r11
0 1 2 3 4 5 6 7
您想要的结果如下所示:
r12
3 4 5 6
也就是说,最终结果将包括r11的低24位和r10的高8位。如果使用无符号算术,则提取位就很简单。由于您使用的是带符号算术,因此需要保留符号。还要注意,必须通过将long long转换为整数来丢弃高8位。
首先,让我们将r11的低24位移到最终位置。算术左移确保符号被保留。
mov r12, r11 asl #8
现在将这些位插入r12中的适当位置。我们已经确保符号对于高位是正确的,所以在这里,只使用逻辑移位。
orr r12, r10 lsr #24
以上相当于这个C:
r12 = ((signed)r11 << 8);
r12 |= ((unsigned)r10 >> 24);
当然,您可以让编译器为您生成这样的代码。为了让编译器在C中正确移位long long,你需要使用:
int res = (acc >> 24LL);