Understanding Base Pointer and Stack Pointers: In Context with gcc Output

前端 未结 3 2369
时光说笑
时光说笑 2021-02-20 03:50

I have the following C program:

int main()
{
    int c[10] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2};
    return c[0];
}

and when compiled using the -S

3条回答
  •  春和景丽
    2021-02-20 04:25

    Also why does gcc not use push instead of movl, to push the array elements onto the stack?

    It is quite rare to have a large initialized array in exactly the right place in the stack frame that you could use a sequence of pushes, so gcc has not been taught to do that. (In more detail: array initialization is handled as a block memory copy, which is emitted as either a sequence of move instructions or a call to memcpy, depending on how big it would be. The code that decides what to emit doesn't know where in memory the block is going, so it doesn't know if it could use push instead.)

    Also, movl is faster. Specifically, push does an implicit read-modify-write of %esp, and therefore a sequence of pushes must execute in order. movl to independent addresses, by contrast, can execute in parallel. So by using a sequence of movls rather than pushes, gcc offers the CPU more instruction-level parallelism to take advantage of.

    Note that if I compile your code with any level of optimization activated, the array vanishes altogether! Here's -O1 (this is the result of running objdump -dr on an object file, rather than -S output, so you can see the actual machine code)

    0000000000000000 
    : 0: b8 00 00 00 00 mov $0x0,%eax 5: c3 retq

    and -Os:

    0000000000000000 
    : 0: 31 c0 xor %eax,%eax 2: c3 retq

    Doing nothing is always faster than doing something. Clearing a register with xor is two bytes instead of five, but has a formal data dependence on the old contents of the register and modifies the condition codes, so might be slower and is thus only chosen when optimizing for size.

提交回复
热议问题