CodeBlanks Logo Icon CodeBlanks

Registers

Specify explicit registers.

Explicit registers

Some instructions use specific registers (for example on x86, mul, div, cpuid, system calls). In such cases the register's name is given in quotes instead of a register class:

let mut x: u64 = 6;
let y: u64 = 7;
unsafe {
    asm!(
        "imul rax, rcx",
        inout("rax") x,
        in("rcx") y,
    );
}
// x == 42

Explicit registers are written in the template by name, not with {}. Some registers (like the stack pointer rsp and the frame pointer rbp) can't be used as operands.

Clobbered registers

mul writes its result to the rdx:rax pair; even if rdx isn't used, it must be declared as clobbered:

let mut a: u64 = 6;
unsafe {
    asm!(
        "mul {b}",
        b = in(reg) 7u64,
        inout("rax") a,
        out("rdx") _,        // rdx clobbered, its value not needed
    );
}

For assembly that calls functions, the clobber_abi("C") option declares all registers the calling convention may clobber at once.

Practice Multiplication with explicit registers

For x86-64, write fn carp(x: u64, y: u64) -> u64 using the instruction imul rax, rcx with explicit registers (x * y on other architectures). Print the result of carp(6, 7).

Starter code

main.rs
fn main() {
    // buraya yaz
}

Sample solution

main.rs
#[cfg(target_arch = "x86_64")]
fn carp(mut x: u64, y: u64) -> u64 {
    // SAFETY: yalnızca rax ve rcx kullanılır ve ikisi de bildirilmiştir.
    unsafe {
        std::arch::asm!(
            "imul rax, rcx",
            inout("rax") x,
            in("rcx") y,
        );
    }
    x
}

#[cfg(not(target_arch = "x86_64"))]
fn carp(x: u64, y: u64) -> u64 {
    x * y
}

fn main() {
    println!("{}", carp(6, 7));
}

Expected output

42

Questions and answers

Review the lesson questions together with their answers. To test yourself, solve the lesson interactively.

1 If an instruction clobbers a register whose value you don't use, what should you do?

  • Tell the compiler with out("reg_name") _ Correct answer
  • Nothing
  • Remove unsafe
  • Always save and restore the register

Explanation: Changing an undeclared register silently breaks a value the compiler kept there: undefined behaviour.

2 Specific register

Question
asm!(
    "imul rax, rcx",
    inout(____) x,
    in("rcx") y,
);
Answer
asm!(
    "imul rax, rcx",
    inout("rax") x,
    in("rcx") y,
);

Explanation: A specific register is chosen by giving its name in quotes.

3 Syntax and meaning

Term Meaning
in(reg) x Compiler picks a register
in("rcx") y rcx required
out("rdx") _ Clobbered register
clobber_abi("C") Calling-convention registers

All lessons in Expert