3 ms·
When I compile it with GCC 12, this machine code results: 1129: f3 0f 1e fa endbr64 112d: 55 push rbp
by msla 2y 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.
- rep_lodsb 2y agoWith 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) 0000000000001125 <main>: 1125: 55 push %rbp 1126: 48 89 e5 mov %rsp,%rbp 1129: b8 01 00 00 00 mov $0x1,%eax 112e: bf 01 00 00 00 mov $0x1,%edi 1133: 48 8d 35 ca 0e 00 00 lea 0xeca(%rip),%rsi # 2004 <_IO_stdin_used+0x4> 113a: ba 0e 00 00 00 mov $0xe,%edx 113f: 0f 05 syscall 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)
- khrbtxyz 2y agoThe exact same thing happens with GCC 12 with 32-bit MIPS. #include <asm/unistd.h> char msg[] = "hello, world!\n"; int main(void) { register int syscall_no asm("v0") = __NR_write; register int arg1 asm("a0") = 1; register char *arg2 asm("a1") = msg; register int arg3 asm("a2") = sizeof(msg) - 1; asm("syscall"); return 0; } root@OpenWrt:~# objdump --disassemble=main ... 00400580 <main>: 400580: 27bdfff8 addiu sp,sp,-8 400584: afbe0004 sw s8,4(sp) 400588: 03a0f025 move s8,sp 40058c: 24020fa4 li v0,4004 400590: 24040001 li a0,1 400594: 3c020041 lui v0,0x41 400598: 24450650 addiu a1,v0,1616 40059c: 2406000e li a2,14 4005a0: 0000000c syscall