Comment by msla
14 days ago
When I compile it with GCC 12, this machine code results:
1129: f3 0f 1e fa endbr64
112d: 55 push rbp
112e: 48 89 e5 mov rbp,rsp
1131: b8 01 00 00 00 mov eax,0x1
1136: bf 01 00 00 00 mov edi,0x1
113b: 48 8d 05 c2 0e 00 00 lea rax,[rip+0xec2] # 2004 <_IO_stdin_used+0x4>
1142: 48 89 c6 mov rsi,rax
1145: ba 0f 00 00 00 mov edx,0xf
114a: 0f 05 syscall
114c: b8 00 00 00 00 mov eax,0x0
1151: 5d pop rbp
1152: c3 ret
Can you spot the error?
. . . . . .
The code biffs rax when it loads the string address, so the system call number is lost, and the code ends up not printing anything. Moving the string assignment to be the very first line in main fixes it.
BTW, Clang 14 with no optimization accepts the code without issue but compiles it without using any of the registers; it just stores the values to memory locations and runs the syscall opcode. With O1 optimization or higher, it optimizes away everything except the syscall opcode.
The exact same thing happens with GCC 12 with 32-bit MIPS.
With an older version, it works (as long as there is no optimization at least, with -O2 all the register init code disappears):
$ gcc -v
... gcc version 10.2.1 20210110 (Debian 10.2.1-6)
No idea why a newer version produces worse code in this case (though of course, this way of doing inline assembly isn't "correct" anyway, so nasal demons may result)