Skip to content

The asm! macro incorrectly zeroes high byte register if both high and low byte registers are used for input, and the low byte input value is zero. #97646

@A1-Triard

Description

@A1-Triard

STR:

Compile the following code for 32-bit target (e.g. i686-unknown-linux-gnu or i686-pc-windows-msvc) in release mode:

use std::arch::asm;

unsafe fn int_21h(al_mode: u8) -> Result<u16, u16> {
    let mut ax: u16;
    let mut flags: u8;
    asm!(
        "int 0x21",
        "mov {ax:x}, ax",
        "lahf",
        ax = out(reg) ax,
        in("ah") 0x3du8,
        in("al") al_mode,
        in("edx") 0u32,
        lateout("ah") flags,
        lateout("al") _,
    );
    if flags & 0x01 == 0 {
        Ok(ax)
    } else {
        Err(ax)
    }
}

fn main() {
    let x = unsafe { int_21h(0) }.unwrap();
    println!("{}", x);
}
$ cargo build --target i686-unknown-linux-gnu --release

Look at the final machine code:

$ objdump -d target/i686-unknown-linux-gnu/release/test_reg_bytes | grep -B 5 "int "

    514a:	5b                     	pop    %ebx
    514b:	b4 3d                	mov    $0x3d,%ah
    514d:	31 d2                	xor    %edx,%edx
    514f:	31 c0                	xor    %eax,%eax
    5151:	81 c3 62 fd 04 00   	add    $0x4fd62,%ebx
    5157:	cd 21                	int    $0x21

AR: As you can see, eax is xored after ah was set to input 0x3d value.

ER: Either the compiler should prevent such high and low byte register usage and refuse to compile such code, either it should not clear ah when it is trying to clear al.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-LLVMArea: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues.A-inline-assemblyArea: Inline assembly (`asm!(…)`)C-bugCategory: This is a bug.O-x86_32Target: x86 processors, 32 bit (like i686-*) (also known as IA-32, i386, i586, i686)O-x86_64Target: x86-64 processors (like x86_64-*) (also known as amd64 and x64)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions