I am just learning about how code actually works. I am a beginner in assembly, mediocre in C and that's all. I read that instructions exist for addition, subtraction, multiplication & division. I got curious and did some simple arithmetic C and converted to assembly. I was blown away by the results.
Addition and subtraction converted directly. But for multiplication, whenever multiplier is a power of 2, it just shifted to left 'power' times. For example x*4
-> sal x, 2
(understandable as shifting is much more fast). On some other occasion, for x*y, it just added x effectively y times!
The confusing bit(reason for this post) is division. I did in C, val/5
(val=45). The compiler converted it as
mov ecx, DWORD PTR v[rip]
mov edx, 1717986919
mov eax, ecx
imul edx
sar edx
mov eax, ecx
sar eax, 31
sub edx, eax
mov eax, edx
I patiently went through it manually and yes, it will produce 9 as the result on eax.(I assumed sar edx
as sar edx, 1
). But what is it doing? How is it getting 1717986919?
When both of values are unknown, compiler have to and does it in normal way. But what kind of optimization is this?(My compiler is gcc-7.5.0)