1

Here's the C program, I use Visual Studio Community 2022 with MSVC compiler. What are all those mov instructions, I don't use any compiler optimization flags.


#include <stdio.h>
int main(void) {
    int a = 11;
    int b = 13;
    a += b;
    a += 15;
    a += 17;
    a += 23;
    return 0;
}

Here's the disassembly view of the running program.

    int a = 11;
00007FF75AB9175D  mov         dword ptr [a],0Bh  
    int b = 13;
00007FF75AB91764  mov         dword ptr [b],0Dh  
    a += b;
00007FF75AB9176B  mov         eax,dword ptr [b]  
00007FF75AB9176E  mov         ecx,dword ptr [a]  
00007FF75AB91771  add         ecx,eax  
00007FF75AB91773  mov         eax,ecx  
00007FF75AB91775  mov         dword ptr [a],eax  
    a += 15;
00007FF75AB91778  mov         eax,dword ptr [a]  
00007FF75AB9177B  add         eax,0Fh  
00007FF75AB9177E  mov         dword ptr [a],eax  
    a += 17;
00007FF75AB91781  mov         eax,dword ptr [a]  
00007FF75AB91784  add         eax,11h  
00007FF75AB91787  mov         dword ptr [a],eax  
    a += 23;
00007FF75AB9178A  mov         eax,dword ptr [a]  
00007FF75AB9178D  add         eax,17h  
00007FF75AB91790  mov         dword ptr [a],eax 
6
  • 4
    "I don't use any compiler optimization flags." that is the reason. For the constant cases, it just reads the variable into a register, adds the constant and writes it back. For the a += b it gets more confused with an extra mov.
    – Jester
    Commented Jul 6 at 14:50
  • 2
    And if you enable optimizations, the compiler will realize that none of the results are actually used, and just keep the return 0;. So zero instructions per addition...
    – BoP
    Commented Jul 6 at 14:56
  • And if you print a after each addition, the optimizer will likely do all the additions at compile time and just print the constant values. To avoid this, you should get the initial values of a and b from user input.
    – Barmar
    Commented Jul 6 at 14:57
  • See How to remove "noise" from GCC/clang assembly output? for how to write functions that compile to asm worth looking at, e.g. int foo(int a, int b){ return a+b; } should compile to one instruction plus a ret (with optimization enabled). Or two if building legacy 32-bit code where the calling convention passes args in stack memory instead of registers. Commented Jul 6 at 23:26
  • It is curious how you told the compiler not to optimise your code, yet you somehow expect that it generates optimised assembly code.
    – fuz
    Commented Jul 8 at 10:57

1 Answer 1

6

Why do I get multiple ASM instructions per addition?

The generated assembly does not have multiple instructions per addition. For the most part, it has one instruction per C “operation.”

The statement a += 15; does not just say to add 15. First, a += 15 is defined to be the same as a = a + 15 (except the location for a is determined only once).1 Then, the specifications of the C standard say these operations will be performed:

  • For the a in a + 15, the value of a will be fetched from memory.2
  • For the +, the value of a and 15 will be added.3
  • For a =, the value resulting from the + will be stored in a.4

That is effectively a load, an add, and a store, which is exactly what we see in the generated assembly:

mov         eax,dword ptr [a]  //  Load the value of a.
add         eax,0Fh            //  Add the value of a and 15.
mov         dword ptr [a],eax  //  Store the new value into a.

Footnotes

1 This is specified in C 2018 6.5.16.2 3: “A compound assignment of the form E1 op= E2 is equivalent to the simple assignment expression E1 = E1 op (E2), except that the lvalue E1 is evaluated only once,…”

2 C 2018 6.3.2.1 2: “Except when it is the operand of the sizeof operator, the unary & operator, the ++ operator, the -- operator, or the left operand of the . operator or an assignment operator, an lvalue that does not have array type is converted to the value stored in the designated object (and is no longer an lvalue); this is called lvalue conversion.

3 C 2018 6.5.6 5: “The result of the binary + operator is the sum of the operands.”

4 C 2018 C 6.5.16.1 2: “In simple assignment (=), the value of the right operand is converted to the type of the assignment expression and replaces the value stored in the object designated by the left operand.”

5
  • 2
    The C standard does not require variables whose address is never taken to be stored anywhere in memory. Giving every variable a stack slot is an extra thing C compilers often do when optimization is off, for the sake of unsophisticated debuggers.
    – zwol
    Commented Jul 6 at 17:20
  • 1
    @zwol: That is post optimization. The C standard specifies the semantics of C programs using an abstract machine model. In that model, every object is a region of memory, and the value of the object is stored in its memory. I cited the specific passages of the C standard that say these things happen, in the model. Commented Jul 6 at 17:21
  • I think you're reading too much into the occasional use of "memory location" to describe objects in the abstract machine. Reread carefully and you should see that the abstract machine's "a region of storage in the execution environment" (3.15, definition of "object") is not required to correspond to what we call "memory" in a concrete machine. I'm not sure if this genuinely affects the semantics of the language or just stuff that can be shoved under the umbrella of valid optimizations / the as-if rule, but it's important to be clear on this sort of thing for pedagogical reasons.
    – zwol
    Commented Jul 7 at 15:05
  • @zwol: I have not said that the storage in the abstract machine is required to correspond to memory in a physical machine. It is, in general, not required. However, this is not a question about optimized code. OP stated they were compiling without optimization and asked about the generated code. I am using the semantics of the abstract model because that explains the generated code for this question. If we used the instructions that are or could be generated with optimization, that would not answer OP’s question. Commented Jul 7 at 15:47
  • @EricPostpischil Thanks a ton for taking the time to give a proper answer to my question. Commented Jul 8 at 11:58

Not the answer you're looking for? Browse other questions tagged or ask your own question.