4 ms·
To be honest, I still like the explicit cobber syntax of rusty_asm. Last year I had some fun getting a rust program to run on some old 386 DOS SBC I had hangin
by Teknoman117 6y ago
To be honest, I still like the explicit cobber syntax of rusty_asm.
Last year I had some fun getting a rust program to run on some old 386 DOS SBC I had hanging around. Was terrible in terms of code density (basically a bunch of 32 bit instructions prefixed with the "execute 32 bit op in real mode" prefix).
This was a wrapper around the DOS string print function (where s is a &str).
rusty_asm! {
let ptr: in("{dx}") = s.as_ptr();
let len: in("{cx}") = s.len();
clobber("ah");
clobber("al");
clobber("bx");
asm("volatile", "intel") {
"mov ah, 0x40
xor bx, bx
int 21h"
}
}
- JoshTriplett 6y agoIn the new syntax, a direct translation of that would look something like this: asm!(" mov ah, 0x40 xor bx, bx int 21h ", in("dx") s.as_ptr(), in("cx") s.len(), out("ax") _, out("bx") _, ) However, I'd personally write that like this instead: asm!( "int 21h", inout("ax") 0x4000 => _, inout("bx") 0 => _, inout("cx") s.len() => _, inout("dx") s.as_ptr() => _, ) That lets the compiler handle filling in ax and bx, and also avoids trusting that the interrupt routine leaves ax/bx/cx/dx untouched. (I might also write clobbers for every other general-purpose register, too. Take a look at Linux arch/x86/boot/bioscall.S and the "Glove box" for BIOS calls, due to misbehaving BIOSes that clobber registers they shouldn't.)
- Teknoman117 6y agoThanks! The latter of the two is definitely nice. Yeah, I should've let the compiler setup ax and bx. Again, this was a hack :)
- josephcsible 6y agoI agree that passing `ax` and `bx` as inputs is better than setting them in the inline asm, but I don't like the idea of setting registers that shouldn't get changed as outputs "just in case".
- JoshTriplett 6y agoIt's not a theoretical consideration. It's quite common for BIOS and firmware code to clobber registers that it isn't supposed to; see the code I mentioned in the Linux kernel, which arose through real-world bugs that were incredibly hard to debug.
- josephcsible 6y agoBut where do you draw the line? What if it clobbers the stack pointer?
- JoshTriplett 6y agoThen it won't be able to return at all, and people will notice more quickly.
- alfiedotwtf 6y ago40Hex :raises eyebrow:
- userbinator 6y agoI thought having the 0x-prefix (which AFAIK is a C-originated syntax) along with the -h suffix (classic PC Asm syntax) together in the same code was unusual too.
- JoshTriplett 6y agoI've programmed for DOS and BIOS before, and using the `h` suffix for `int 21h` and `int 20h` and `int 10h` and `int 13h` still feels natural. I never wrote `h` literals for anything but a few interrupt numbers, though. And when I programmed for 32-bit Linux, `int 0x80` felt more natural.