Assembly 在树莓圆周率上组装——乘以两个大数字给了我一个令人惊讶的结果
我只是在我的覆盆子圆周率上搞组装:Assembly 在树莓圆周率上组装——乘以两个大数字给了我一个令人惊讶的结果,assembly,arm,raspberry-pi3,Assembly,Arm,Raspberry Pi3,我只是在我的覆盆子圆周率上搞组装: global _start _start: mov r0, #0x7fffffff mov r1, #0x7fffffff muls r2, r0, r1 我原以为r2中会出现一些奇怪的结果,CPSR集合中会出现溢出位,但结果却是: r0 0x7fffffff 0x7fffffff r1 0x7fffffff
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=0x3fffffff0000001 由于该结果的最低有效32位是0x00000001,因此结果为1也就不足为奇了
至于为什么它没有设置溢出标志,答案是因为它没有。从历史上看,早期的ARM实现是就地实现的,因此需要注意的是,C和V标志在ARMv5之前已损坏(因为ALU中发生移位和加法),并且在ARMv6之前,两个操作数必须位于不同的寄存器中(因为否则,将中间结果写回一个操作数也会损坏另一个操作数并产生无意义的结果)。乘法器实现可能已经有所改进(除了节省空间的Cortex-M0“小乘法器”选项外,迭代算法早已过时),使原来的限制没有意义,但架构行为仍然存在。0x7FFFFFFF*0x7FFFFFFF=0x3FFFFFFF00000001 由于该结果的最低有效32位是0x00000001,因此结果为1也就不足为奇了
至于为什么它没有设置溢出标志,答案是因为它没有。从历史上看,早期的ARM实现已经实现,因此需要注意的是,C和V标志在ARMv5之前已经损坏(因为ALU中发生了移位和添加)在ARMv6之前,两个操作数必须在不同的寄存器中(因为否则,将中间结果写回一个操作数也会损坏另一个操作数,并产生无意义的结果)。从那时起,乘法器实现可能有所改进(除了节省空间的Cortex-M0“小乘法器”之外)选项,迭代算法早已过时),使原来的限制变得毫无意义,但架构行为仍然存在。打开桌面计算器应用程序,将其切换到“程序员”模式,键入7fffffff*7fffffff,然后查看。您看到了什么?C标志=未受影响/*请参阅“C标志”注意*/V Flag=未受某些arm文档的影响如果S==1,则N和Z受影响谢谢。打开桌面计算器应用程序,将其切换到“程序员”模式,键入7fffffff*7fffffff,然后查看。您看到了什么?C Flag=未受影响/*请参阅“C Flag”注*/V Flag=未受某些arm文档的影响如果S==1,则N和Z均受影响谢谢。