臂汇编器在乘长后右移?

发布于 2024-09-06 12:40:34 字数 680 浏览 3 评论 0原文

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

-谢谢,

Newbie ARM assembler question. I am writing my first arm assembler program and I am trying to code this C fragment.

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;

I have coded the first part and computed the sum in r10, r11 registers.

@ 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

Now I need to extract the value of "res" back from the r10 and r11 registers by right shifting the "long long" by 24 bits. How do I do that ?

-thanks,

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

水波映月 2024-09-13 12:40:34

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);

r10 contains the lower 32-bits, and r11 contains the upper 32-bits.

r10           r11
0  1  2  3    4  5  6  7

The result you want looks like this:

r12
3  4  5  6

That is, the final result will include lower 24 bits of r11 and the upper 8 bits of r10. If you use unsigned arithmetic, extracting the bits is that simple. Since you're using signed arithmetic, you need to preserve the sign. Also note that of necessity, you are also discarding the upper 8 bits by converting long long into an integer.

First, let's move lower 24 bits of r11 into their final position. The arithmetic left shift ensures that the sign is preserved.

mov r12, r11 asl #8

Now insert these bits into the appropriate place in r12. We already ensured that the sign was correct for the upper bits, so here, just use a logical shift.

orr r12, r10 lsr #24

The above is equivalent to this C:

r12 = ((signed)r11 << 8);
r12 |= ((unsigned)r10 >> 24);

You can, of course, just let the compiler generate code like this for you. To get the compiler to shift a long long correctly in C you would need to use:

int res = (acc >> 24LL);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文