The code snippet below compiles correctly without optimization, but with the optimization flag turned on (at least with -O2) the compiler wrongly assumes that the register %edx was not modified by the inline assembly statement. The bug can be reproduced by issuing the following command.
To reproduce the bug, compile the code snippet bellow with the command gcc -S -O2 file.c and look the file file.s in the lines between the to #APP sections. See bellow, after the source file, the assembly code produced with and without optimization. /********* file.c *************************************/ #define rsmpl8b(addr, d1, d2) __asm__ __volatile__(\ "outb %%al, %%dx\n\t" \ "movb %%cl, %%al\n\t" \ "addw $2, %%dx\n\t" \ "outb %%al, %%dx\n\t" \ : : "a" (d1), "c" (d2), "d" (addr)) void teste() { int i; unsigned short base_addr = 0x378; for (i = 0; i < 0x1000; i++) { rsmpl8b(base_addr, 0xFF, 0xFE); rsmpl8b(base_addr, 0xFD, 0xFC); } } /*************** file.s compiled with gcc -S -O2 file.c *****/ .file "file.c" .text .globl teste .type teste, @function teste: pushl %ebp movl $888, %edx movl %esp, %ebp pushl %edi movl $255, %edi pushl %esi movl $254, %esi pushl %ebx movl $253, %ebx subl $4, %esp movl $0, -16(%ebp) .p2align 4,,15 .L2: movl %edi, %eax movl %esi, %ecx #APP outb %al, %dx movb %cl, %al addw $2, %dx outb %al, %dx #NO_APP movl $252, %ecx movl %ebx, %eax #APP outb %al, %dx movb %cl, %al addw $2, %dx outb %al, %dx #NO_APP incl -16(%ebp) cmpl $4096, -16(%ebp) jne .L2 popl %eax popl %ebx popl %esi popl %edi popl %ebp ret .size teste, .-teste .ident "GCC: (GNU) 4.1.2 20070214 ( (gdc 0.24, using dmd 1.020)(Gentoo 4.1.2p1.0.2)" .section .note.GNU-stack,"",@progbits /*************** file.s compiled with gcc -S file.c *********/ .file "file.c" .text .globl teste .type teste, @function teste: pushl %ebp movl %esp, %ebp subl $16, %esp movw $888, -2(%ebp) movl $0, -8(%ebp) jmp .L2 .L3: movl $255, %eax movl $254, %ecx movzwl -2(%ebp), %edx #APP outb %al, %dx movb %cl, %al addw $2, %dx outb %al, %dx #NO_APP movl $253, %eax movl $252, %ecx movzwl -2(%ebp), %edx #APP outb %al, %dx movb %cl, %al addw $2, %dx outb %al, %dx #NO_APP incl -8(%ebp) .L2: cmpl $4095, -8(%ebp) jle .L3 leave ret .size teste, .-teste .ident "GCC: (GNU) 4.1.2 20070214 ((gdc 0.24, using dmd 1.020)) (Gentoo 4.1.2p1.0.2)" .section .note.GNU-stack,"",@progbits -- Summary: wrong assumption about registers used in asm statements Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: critical Priority: P3 Component: inline-asm AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: jlima at sim dot ul dot pt GCC host triplet: i386-linux-gnu GCC target triplet: i386-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=36051