在 raspberry pi 上组装 - 将两个大数相乘得到了一个令人惊讶的结果

assembly on a raspberry pi - multiplying two large numbers is giving me a surprising result

我只是在我的 raspberry pi 上搞组装:

global _start

_start:         mov r0, #0x7fffffff
                mov r1, #0x7fffffff
                muls r2, r0, r1

我预计 r2 会出现一些奇怪的结果,并且 CPSR 集中会出现溢出位,但我却得到了:

r0             0x7fffffff       0x7fffffff
r1             0x7fffffff       0x7fffffff
r2             0x1      0x1
cpsr           0x10     0x10 (a 0 overflow bit)

这太愚蠢了,太简单了,我已经准备好接受满脸的反驳,但我已经盯着它看了一会儿,并在谷歌上搜索了一堆。谁能告诉我为什么 r2 中的 #1,以及为什么对一个大数求平方不会溢出?

0x7FFFFFFF * 0x7FFFFFFF = 0x3FFFFFFF00000001

因为 mul returns the least-significant 32 bits of the result,并且该结果的最低有效 32 位是 0x00000001,所以结果为 1 应该不足为奇。

至于为什么不设置溢出标志,嗯,答案是因为它没有。从历史上看,早期的 ARM 实现就地实现 Booth's algorithm,因此请注意 C 和 V 标志在 ARMv5 之前已损坏(因为 ALU 中发生的移位和加法)并且两个操作数必须在ARMv6 之前的不同寄存器(因为否则将中间结果写回一个操作数也会破坏另一个操作数并产生无意义的结果)。乘法器的实现可能有所改进(除了 space-saving Cortex-M0 "small multiplier" 选项,迭代算法早已失效),使得原始限制没有实际意义,但架构行为仍然存在。