是否有可能通过使用纯位加法,减法除以10的无符号整数,也许繁衍?使用资源非常有限且速度慢的处理器.
据我所知,大多数编译器会通过乘法然后向右移位进行快速除法.例如,如果你检查这个SO线程,它会说当你要求Microsoft编译器除以10时,它会将被除数乘以0x1999999A(即2 ^ 32/10),然后将结果除以2 ^ 32(使用32向右移动).
到现在为止还挺好.
但是,一旦我使用GCC在ARM上测试了相同的除法,但编译器做了一些略微不同的事情.首先,它将被除数乘以0x66666667(2 ^ 34/10),然后将结果除以2 ^ 34.到目前为止,除了使用更高的乘数之外,它与Microsoft相同.然而,在那之后,它从结果中减去(被除数/ 2 ^ 31).
我的问题:为什么在ARM版本上有额外的减法?你能给我一个数字例子,如果没有减法,结果会出错吗?
如果你想检查生成的代码,它在下面(带我的评论):
ldr r2, [r7, #4] @--this loads the dividend from memory into r2
movw r3, #:lower16:1717986919 @--moves the lower 16 bits of the constant
movt r3, #:upper16:1717986919 @--moves the upper 16 bits of the constant
smull r1, r3, r3, r2 @--multiply long, put lower 32 bits in r1, higher 32 in r3
asr r1, r3, #2 @--r3>>2, then store in r1 (effectively …Run Code Online (Sandbox Code Playgroud) 我不明白这段代码中发生了什么.C代码是:
#include <stdio.h>
int main()
{
const int mul = 100;
int x;
printf_s("Input a number\r\n");
scanf_s("%i", &x);
printf_s("%i/%i = %i\r\n", x, mul, x / mul);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我期望得到的程序集将是一些简单的移位和添加/子操作,但是有一些神奇的常量,如51EB851Fh乘法,等等.这里发生了什么?
; int __cdecl main()
_main proc near
x= dword ptr -8
var_4= dword ptr -4
push ebp
mov ebp, esp
sub esp, 8
mov eax, ___security_cookie
xor eax, ebp
mov [ebp+var_4], eax
push offset Format ; "Input a number\r\n"
call ds:__imp__printf_s
lea eax, [ebp+x]
push eax
push offset …Run Code Online (Sandbox Code Playgroud)