Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Where is the one to one correlation between the assembly and cpp code?

Tags:

c++

assembly

I tried to examine how the this code will be in assembly:

int main(){
  if (0){
    int x = 2;
    x++;
  }
  return 0;
}

I was wondering what does if (0) mean?

I used the shell command g++ -S helloWorld.cpp in Linux

and got this code:

    .file   "helloWorld.cpp"
    .text
    .globl  main
    .type   main, @function
main:
.LFB0:
    .cfi_startproc
    pushq   %rbp
    .cfi_def_cfa_offset 16
    .cfi_offset 6, -16
    movq    %rsp, %rbp
    .cfi_def_cfa_register 6
    movl    $0, %eax
    popq    %rbp
    .cfi_def_cfa 7, 8
    ret
    .cfi_endproc
.LFE0:
    .size   main, .-main
    .ident  "GCC: (Ubuntu/Linaro 4.6.1-9ubuntu3) 4.6.1"
    .section    .note.GNU-stack,"",@progbits
  1. I expected that the assembly will contain some JZ but where is it?
  2. How can I compile the code without optimization?
like image 408
0x90 Avatar asked Apr 14 '26 23:04

0x90


2 Answers

There is no direct, guaranteed relationship between C++ source code and the generated assembler. The C++ source code defines a certain semantics, and the compiler outputs machine code which will implement the observable behavior of those semantics. How the compiler does this, and the actual code it outputs, can vary enormously, even over the same underlying hardware; I would be very disappointed in a compiler which generated code which compared 0 with 0, and then did a conditional jump if the results were equal, regardless of what the C++ source code was.

In your example, the only observable behavior in your code is to return 0 to the OS. Anything the compiler generates must do this (and have no other observable behavior). The code you show isn't optimal for this:

xorl %eax, %eax
ret

is really all that is needed. But of course, the compiler is free to generate a lot more if it wants. (Your code, for example, sets up a frame to support local variables, even though there aren't any. Many compilers do this systematically, because most debuggers expect it, and get confused if there is no frame.)

With regards to optimization, this depends on the compiler. With g++, -O0 (that's the letter O followed by the number zero) turns off all optimization. This is the default, however, so it is effectively what you are seeing. In addition to having several different levels of optimization, g++ supports turning individual optimizations off or on. You might want to look at the complete list: http://gcc.gnu.org/onlinedocs/gcc-4.6.2/gcc/Optimize-Options.html#Optimize-Options.

like image 199
James Kanze Avatar answered Apr 16 '26 14:04

James Kanze


The compiler eliminates that code as dead code, e.g. code that will never run. What you're left with is establishing the stack frame and setting the return value of the function. if(0) is never true, after all. If you want to get JZ, then you should probably do something like if(variable == 0). Keep in mind that the compiler is in no way required to actually emit the JZ instruction, it may use any other means to achieve the same thing. Compiling a high level language to assembly is very rarely a clear, one-to-one correlation.

like image 36
Daniel Kamil Kozar Avatar answered Apr 16 '26 16:04

Daniel Kamil Kozar



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!