https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108539
Bug ID: 108539 Summary: Wrong register usage for -m16 -masm=intel -march=i386 on asm volatile Product: gcc Version: 12.1.0 Status: UNCONFIRMED Severity: normal Priority: P3 Component: c++ Assignee: unassigned at gcc dot gnu.org Reporter: arheik at dnainternet dot net Target Milestone: --- Consider the following code (test.cpp): void test(unsigned char& a, unsigned char& b) { unsigned char _a, _b; asm volatile( "mov dx, 0\n" "mov bx, 0\n" : "=dl" (_a), "=dh" (_b) : : "bx" ); a = _a; b = _b; } void main(void) { unsigned char a, b; test(a, b); } Compiled with: g++ -m16 -masm=intel -march=i386 -ffreestanding -fno-inline -mregparm=3 -fno-dwarf2-cfi-asm -fno-asynchronous-unwind-tables -fno-ident -O2 test.cpp -o - -S This generates for test(): _Z4testRhS_: .LFB0: push esi .LCFI0: push ebx .LCFI1: mov ecx, edx #APP # 4 "test.cpp" 1 mov dx, 0 mov bx, 0 # 0 "" 2 #NO_APP mov ebx, esi mov BYTE PTR [eax], bl mov BYTE PTR [ecx], dl pop ebx .LCFI2: pop esi .LCFI3: ret In which bl usage is clearly wrong (dh is missing) and ebx/eax/esi usage looks suspect. Compling with -mregparm=0 produces for test(): _Z4testRhS_: .LFB0: push ebx .LCFI0: #APP # 4 "test.cpp" 1 mov dx, 0 mov bx, 0 # 0 "" 2 #NO_APP mov eax, DWORD PTR 8[esp] mov BYTE PTR [eax], cl mov eax, DWORD PTR 12[esp] mov BYTE PTR [eax], dl pop ebx .LCFI1: ret Which should use dh instead of cl.