When writing functions like interrupt handlers, the programmer needs to have absolute control over the CPU registers and memory, which means that other ABIs might not be able to cut it.
This extern "none"
ABI would be similar to naked functions, but you could write regular Rust code in it.
This could be done by requiring the programmer to declare a custom prologue and epilogue at the start and end of the function (which would be guaranteed to run first and last) like this:
unsafe extern "none" fn syscall_handler() {
unsafe {
asm! {
// save registers to variables
}
}
// handler logic here
unsafe {
asm! {
// set the registers back to how they were
}
}
}
I am aware that LLVM uses the rbx
register for its own purposes, but I hope there might be a way to guarantee that LLVM will not modify it before it's saved by the caller.
Another way would be to make the signature of these functions have to be fn(Registers) -> Registers
, but that's not great (i.e. maybe you don't care about preserving all the registers).
Introducing new syntax could work (this isn't a very thought-out idea, it probably has many of the problems that the second idea has):
// perhaps a `preserve(...)` keyword could work
unsafe extern "none" fn syscall_handler(eax: u32, ebx: u32) -> { eax, ebx, /* preserve(ecx, edx, ...) */ } {
// handler code
}