Understanding MSVS C ++ Compiler Optimization

I do not understand what is going on in this code. Code 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; } 

I was expecting the resulting assembly to be a few simple shifts and add / sub-operations, but there are some magic constants like 51EB851Fh , multiplications, etc. What's going on here?

 ; 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 aI ; "%i" call ds:__imp__scanf_s mov ecx, [ebp+x] mov eax, 51EB851Fh imul ecx sar edx, 5 mov eax, edx shr eax, 1Fh add eax, edx push eax push 64h push ecx push offset aIII ; "%i/%i = %i\r\n" call ds:__imp__printf_s mov ecx, [ebp+var_4] add esp, 1Ch xor ecx, ebp ; cookie xor eax, eax call @__security_check_cookie@4 ; __security_check_cookie(x) mov esp, ebp pop ebp retn _main endp 
+8
c ++ optimization c assembly visual-studio
source share
2 answers

Processors are not very good at partitioning, idiv can take from 11 to 18 cycles. Unlike shifts and multiplications, they usually take only one cycle.

Thus, the optimizer replaced your division by multiplication using fixed-point math, using 32-bit multiplication, generating a 64-bit result in edx: eax. Reverse envelope: n / 100 == n * 0.32 / 32 == n * (0.32 * pow (2.32)) / 32 / pow (2.32). These units are very cheap, it's just a change. And the multiplier becomes 0.32 * pow (2.32) ~ = 1374389535 == 0x51EB851F

+11
source share

51EB851Fh seems like a magic number for a divider to divide by 100

Source: http://masm32.com/board/index.php?topic=1906.0 Answer # 2

0
source share

All Articles