Assembly versus C code

I am currently studying assembly and C programming languages, and I have a few questions about this.

C code

int arith(int x, int y, int z) { int t1 = x + y; int t2 = z*48; int t3 = t1 & 0xFFFF; int t4 = t2 * t3; return t4; } 

Build code

 movl 16(%ebp),%eax z leal (%eax,%eax,2), %eax z*3 sall $4,%eax t2 = z*48 movl 12(%ebp),%edx y addl 8(%ebp),%edx t1 = x+y andl $65535,%edx t3 = t1&0xFFFF imull %edx,%eax Return t4 = t2*t3 

Instead of using leal and then shifting by 4 to multiply z by 48, could I just use imull $ 48,% eax?

In addition, the% edx register is used several times. Does this mean that t1 is overwritten? In other words, can I get t1 right before t4 if I want?

+5
source share
1 answer

Trying to match the assembly with your code line by line may not be the best way to get close to this. The compiler makes several optimizations to make your program as efficient as possible, so you may notice some inconsistencies between your code.

To answer your first question, technically this will work, but once again the compiler will make several optimizations. Therefore, although it may seem more intuitive to use imul, the compiler has determined that leal and sall are more efficient. EDIT: I just want to note that bit shift operators are almost always used instead of imul whenever possible. The bit shift is much cheaper for the CPU, since it literally just shifts the bit values, rather than trying to perform some mathematical operation, which may take more processor time.

Now about the "rewriting" t1. The Assembly does not have any information about your program variables - all it knows is that it needs to perform some operations on certain values. Although the assembly can potentially use 4 different registers for storing t1-4, the compiler has determined that this is not necessary, and you only need 2 registers for all values. If you think about it, this should make sense. Your function can be reduced to a few lines of code. Obviously, this is not a good idea, since it would make reading impossible, but the assembly does not have to be readable. If you went back to your program and performed some other operation with t1 before returning t4, you may notice that your assembly is different from the previous one and that it may use a different register depending on how this value is used.

If you really want to use the barebone version of your program in the assembly, compile it with the -Og flag to disable compiler optimization. This may still not match your code, but it may make it easier for you to understand what is going on.

+2
source

Source: https://habr.com/ru/post/1247794/


All Articles