The NetBSD i386 kernel sets up the IDT using code that end up (after some inlining done with -Os or -O3) looking like:
struct region_descriptor { int rd_base; int rd_limit; }; struct gate_descriptor { int x; } *idt; static __inline void lidt(struct region_descriptor *p) { __asm volatile("lidt (%0)" : : "r" (p)); } void set_idt1(void) { struct region_descriptor region; region.rd_limit = (int)1024; region.rd_base = (int)idt; lidt(®ion); } gcc 4.1.2 optimises out the assignments to 'region', so the lidtl instruction loads a garbage vector table. Changing the lidt function to: static __inline void lidt(void *vp) { int *p = vp; __asm volatile("lidt %0" : : "m" (*p)); } seems to fix this case. But I can't see how to enforce the assignments to: - a variable size buffer - a buffer which must be specified in a register in the assembler opcode. both of which might happen trying to write the pattern for 'rep outsb'. David -- Summary: Assignment to data used in __asm() get optimised away. Product: gcc Version: 4.1.2 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: dsl at netbsd dot org GCC host triplet: i386--netbsdelf http://gcc.gnu.org/bugzilla/show_bug.cgi?id=28729