example-greenthreads icon indicating copy to clipboard operation
example-greenthreads copied to clipboard

Compiler friendly inline assembly code

Open jordanisaacs opened this issue 3 years ago • 1 comments

As I followed along the book I got compiler warnings about llvm_asm!() and the use of naked functions. It says the warnings will become errors eventually due to deprecation. It seems there has been some recent work to switch to asm!() and some more restrictions on the use of #[naked].

I rewrote the assembly code to fit the new style correctly I believe. I am new to assembly code so some of this might not be right but it compiles correctly on windows. I am unsure if extern "C" was the correct choice, but it solved the ABI warning while still compiling. Also, you need options(noreturn) with the asm!() macro in naked functions so I added ret which I believe is the right assembly command.

The docs would also need to be updated as also it changes the syntax from at&t to intel (the new default in asm!() macro). And the docs could just link to the unstable book for a better description on how the asm! macro works as it is well written.


Moving context parameters

Old:

llvm_asm!(
    "mov $0, %rdi
     mov $1, %rsi"::"r"(old), "r"(new)
);

New:

asm!(
    "mov rdi, {0}",
    "mov rsi, {1}",
    in(reg) old,
    in(reg) new,
);

Skip function

Old:

#[naked]
fn skip() { }

New:

#[naked]
unsafe extern "C" fn skip() {
    asm!("ret", options(noreturn));
}

Switch function

Old:

#[naked]
#[inline(never)]
unsafe fn switch() {
    llvm_asm!("
        mov     %rsp, 0x00(%rdi)
        mov     %r15, 0x08(%rdi)
        mov     %r14, 0x10(%rdi)
        mov     %r13, 0x18(%rdi)
        mov     %r12, 0x20(%rdi)
        mov     %rbx, 0x28(%rdi)
        mov     %rbp, 0x30(%rdi)

        mov     0x00(%rsi), %rsp
        mov     0x08(%rsi), %r15
        mov     0x10(%rsi), %r14
        mov     0x18(%rsi), %r13
        mov     0x20(%rsi), %r12
        mov     0x28(%rsi), %rbx
        mov     0x30(%rsi), %rbp
        "
    );
}

New:

#[naked]
#[inline(never)]
unsafe extern "C" fn switch() {
    asm!(
        "mov [rdi + 0x00], rsp",
        "mov [rdi + 0x08], r15",
        "mov [rdi + 0x10], r14",
        "mov [rdi + 0x18], r13",
        "mov [rdi + 0x20], r12",
        "mov [rdi + 0x28], rbx",
        "mov [rdi + 0x30], rbp",
    
        "mov rsp, [rsi + 0x00]",
        "mov r15, [rsi + 0x08]",
        "mov r14, [rsi + 0x10]",
        "mov r13, [rsi + 0x18]",
        "mov r12, [rsi + 0x20]",
        "mov rbx, [rsi + 0x28]",
        "mov rbp, [rsi + 0x30]",
        "ret",
        options(noreturn)
    )
}





jordanisaacs avatar May 27 '21 23:05 jordanisaacs

Thanks and sorry for the late reply. I'm a bit swamped right now but I've briefly read through this and it looks good. I've been wanting to migrate the whole book over to the new syntax for a while.

However, I'll need to update the "introduction to inline assembly" chapter and the other examples as well for which I'll need some time. I'll see if I can pull these PR's out in a separate branch until everything is covered.

I greatly appreciate the contribution

cfsamson avatar Jun 05 '21 09:06 cfsamson

Just going through open issues and noticed this one that was fixed in the latest revision of the book where all the asm code was migrated to the new syntax.

cfsamson avatar Aug 11 '22 08:08 cfsamson