Having this piece of code:
int main(){
int x = 13;
goto f;
asm __volatile__ (".byte 0xff");
f:
return 0;
}
I don't understand why g++ optimize it and does not include the opcode(in the disassembly):
# 5 "q.c" 1
.byte 0xff
# 0 "" 2
even if I do compile without any optimization at all:
g++ -g -O0 -S q.c
. I tried with g++ -g
and g++ -O0
alone because I read it might not be compatible in some situations.
If I comment the goto f;
line it will insert the opcode.
.file "q.c"
.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 $13, -4(%rbp)
#APP
# 5 "q.c" 1<<<<<<<<<<
.byte 0xff<<<<<<<<<<
# 0 "" 2<<<<<<<<<<
.L2:
#NO_APP
movl $0, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3"
.section .note.GNU-stack,"",@progbits
Does g++ not include a piece of code if it is not going to be used even if I compile with no optimization at all?
I want to know why it does not include that piece of code not finding another solutions.
I read in the comments that : It is bad code. But what if I want to have it? What if I want to have a piece of code injected right there that does not do anything by itself? Does g++ restricts me ?
Because it's dead code is not an explanation. I compiled this code on Windows VS2012
int main() {
std::cout << "something ";
goto foo;
__asm _emit 0xff
__asm _emit 0xfe;
foo :
std::cout << "other thing";
}
Guess what? When it is compiled with Debug configuration the asm code it is included in the binary:
.text:00414ECE push offset aSomething ; "something "
.text:00414ED3 mov eax, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
.text:00414ED8 push eax
.text:00414ED9 call loc_41129E
.text:00414EDE add esp, 8
.text:00414EE1 jmp short loc_414EE7
.text:00414EE1 ; ---------------------------------------------------------------------------
.text:00414EE3 db 0EBh ; d
.text:00414EE4 db 2
.text:00414EE5 db 0FFh<<<<<<<<<<<<<<
.text:00414EE6 db 0FEh ; ¦<<<<<<<<<<<<
.text:00414EE7 ; ---------------------------------------------------------------------------
.text:00414EE7
.text:00414EE7 loc_414EE7: ; CODE XREF: main+31j
.text:00414EE7 push offset aOtherThing ; "other thing"
.text:00414EEC mov eax, ds:__imp_?cout@std@@3V?$basic_ostream@DU?$char_traits@D@std@@@1@A ; std::basic_ostream<char,std::char_traits<char>> std::cout
.text:00414EF1 push eax
.text:00414EF2 call loc_41129E
.text:00414EF7 add esp, 8
.text:00414EFA jmp short loc_414EFE
Interestingly, all the compilers I could try (gcc, llvm-gcc, icc, clang) optimize out the code.
As a workaround, you can include the goto in the asm itself:
__asm__ __volatile__ (
"jmp 1f\n\t"
".byte 0xff\n\t"
"1:");
This is unfortunately architecture specific, while your original code might not be. For that case, the best I could think of is:
volatile int false = 0;
if (false) __asm__ __volatile__ (".byte 0xff");
Of course this incurs a runtime load and test. Both of these work even with optimizations enabled.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With