【问题标题】:32 bit limitation of MUL in ARM Assembly [closed]ARM 汇编中 MUL 的 32 位限制 [关闭]
【发布时间】:2016-10-23 06:17:30
【问题描述】:

在 ARM 汇编中,每个寄存器可以包含存储在其中的 32 位/1 个字的信息。这就是为什么当你尝试存储一个大于 255 的值时它会给你一个错误

但是,MUL 指令似乎没有这个限制。您可以将两个寄存器相乘,每个寄存器的值都为 255,然后将结果存储在第三个寄存器中而不会出现任何错误。这是怎么发生的?目标寄存器不应该不能存储超过 255 的值吗?

【问题讨论】:

  • 255 是一个无符号 byte,8 位。也许您向我们展示了一些代码以及您遇到的错误,以便我们可以解释发生了什么并实际帮助您。
  • 我们假设您指的是 32 位 ARM 架构;但是,那里有 64 位 ARMv8 单元;例如,Cortex-A53、A57。尽管如此,如果我们假设一个 32 位通用寄存器,那么尝试执行类似 mov r1,#0xfffffffff 的操作将在编译期间导致无效常量错误。否则,对 0xffffffff 之类的数字进行加法或乘法肯定会导致溢出,如果您在代码中没有考虑到这一点,那么从数学上讲,您的结果将被其他人解释为“错误”。正如@dwelch 所指出的,2^32 * 2^32 = 2^64。在这种情况下,您将需要更多寄存器
  • 我投票决定将此问题作为题外话结束,因为最好将其发送给softwareengineering.stackexchange.com

标签: assembly arm keil


【解决方案1】:

32 位的最大大小为 0xFFFFFFFF(约 40 亿),因此 0xFF(即 255)乘以 0xFF 为 0xFE01(65025),远小于 40 亿。

你确实提出了一个有趣的话题,那就是你不能乘以 0xFFFFFFFF x 0xFFFFFFFF 而不会溢出。我不相信“它给你一个错误”,它只是截断结果。

【讨论】:

  • ARM mul 指令被明确定义为产生结果的最低有效位 32 位,但是(因此不需要担心有符号/无符号的区别),它可能会让这件事变得不那么有趣。
  • 从小学开始,我们就记得 (x^2) * (x^3) = x^(2+3)。因此,将 x 视为 2,二进制。如果你将 2^31 * 2^31 相乘,你会立即得到 2^62,这是一个溢出,然后你必须考虑是否有可能超出这个范围。并且 0xFF * 0xFF 和任何其他全一乘以与您的计算器进行无符号乘法的全一,可能除了 1 * 1 或其他类似的小数字之外,将再溢出一位。因此,在 0xFF * 0xFF 的情况下,我们的 msbits 是 2^7,给我们 2^14 进位,另外 2^15 需要 16 位来存储该结果。
  • 大多数 32 位操作数的组合不适合无符号乘法的 32 位结果。与组装或手臂完全无关。我们从 C 或其他语言中知道这一点,对于任何其他具有相同大小结果的乘法指令集也是如此。我也希望有符号乘法会出现类似的情况。至少有一个 ARM ARM 显示受影响的标志是 N 和 Z,所以没有溢出的迹象,你只需要像在高级语言中处理它一样处理它。
猜你喜欢
  • 1970-01-01
  • 2011-05-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-15
相关资源
最近更新 更多