2

新手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”的值。我怎么做 ?

-谢谢,

4

1 回答 1

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);
于 2010-06-24T09:54:35.500 回答