moros
moros copied to clipboard
Add assembler and disassembler commands
This PR is a continuation of #549 where we added the iced-x86 crate and a --dissamble option to the elf command. It can't be merged in MOROS v0.10.1 because it makes the kernel larger that the 2MB limit required by the location of the superblock on the disk.
https://github.com/icedland/iced/tree/master/src/rust/iced-x86
We now have a trivial assembler that can assemble two kinds of instruction!
We can write with it a program to halt the system by sending 0xDEAD to the kernel with the STOP syscall (sending 0xCAFE would reboot it instead).
~
> read assembly/dead.asm
main:
mov eax, 0xA
mov edi, 0xDEAD
int 0x80
~
> asm assembly/dead.asm => dead
DEBUG: Label("main")
DEBUG: Instr(["mov", "eax", "0xA"])
DEBUG: Instr(["mov", "edi", "0xDEAD"])
DEBUG: Instr(["int", "0x80"])
~
> hex dead
00000000: 7F42 494E B80A 0000 00BF ADDE 0000 CD80 .BIN. ..........
~
> dead
[42.914465] ACPI Shutdown
Another program that use an invalid 0xBEEF code to STOP and then use EXIT to return:
~
> read assembly/beef.asm
mov eax, 0xA
mov edi, 0xBEEF
int 0x80
mov eax, 0x1
mov edi, 0x0
int 0x80
~
> asm assembly/beef.asm => beef
DEBUG: Instr(["mov", "eax", "0xA"])
DEBUG: Instr(["mov", "edi", "0xBEEF"])
DEBUG: Instr(["int", "0x80"])
DEBUG: Instr(["mov", "eax", "0x1"])
DEBUG: Instr(["mov", "edi", "0x0"])
DEBUG: Instr(["int", "0x80"])
~
> hex beef
00000000: 7F42 494E B80A 0000 00BF EFBE 0000 CD80 .BIN. ..........
00000010: B801 0000 00BF 0000 0000 CD80 ............
~
> beef
DEBUG: STOP SYSCALL: Invalid code '0xbeef' received
Not too far from hello world:
~
> read assembly/hello.asm
main:
mov rax, 0x4
mov rdi, 0x1
mov rsi, hello
mov rdx, 0x2
int 0x80
mov rax, 0x1
mov rdi, 0x0
int 0x80
hello: db 0x48, 0x69
~
> asm assembly/hello.asm => hello
DEBUG: Label("main")
DEBUG: Instr(["mov", "rax", "0x4"])
DEBUG: Instr(["mov", "rdi", "0x1"])
DEBUG: Instr(["mov", "rsi", "text"])
DEBUG: Instr(["mov", "rdx", "0x2"])
DEBUG: Instr(["int", "0x80"])
DEBUG: Instr(["mov", "rax", "0x1"])
DEBUG: Instr(["mov", "rdi", "0x0"])
DEBUG: Instr(["int", "0x80"])
DEBUG: Label("text")
DEBUG: Instr(["db", "0x48", "0x69"])
~
> hex hello
00000000: 7F42 494E 48B8 0400 0000 0000 0000 48BF .BINH.........H.
00000010: 0100 0000 0000 0000 488D 3522 0000 0048 ........H.5"...H
00000020: BA02 0000 0000 0000 00CD 8048 B801 0000 ...........H....
00000030: 0000 0000 0048 BF00 0000 0000 0000 00CD .....H..........
00000040: 8048 69 .Hi
~
> hello
Hi
db need more than two operands and it'd also be good to have string support.
~
> asm assembly/hello.asm => hello
DEBUG: Label("main")
DEBUG: Instr(["mov", "rax", "0x4"])
DEBUG: Instr(["mov", "rdi", "0x1"])
DEBUG: Instr(["mov", "rsi", "text"])
DEBUG: Instr(["mov", "rdx", "0x6"])
DEBUG: Instr(["int", "0x80"])
DEBUG: Instr(["mov", "rax", "0x1"])
DEBUG: Instr(["mov", "rdi", "0x0"])
DEBUG: Instr(["int", "0x80"])
DEBUG: Label("text")
DEBUG: Instr(["db", "0x48", "0x65", "0x6C", "0x6C", "0x6F", "0xA"])
~
> hex hello
00000000: 7F42 494E 48B8 0400 0000 0000 0000 48BF .BINH.........H.
00000010: 0100 0000 0000 0000 488D 3522 0000 0048 ........H.5"...H
00000020: BA06 0000 0000 0000 00CD 8048 B801 0000 ...........H....
00000030: 0000 0000 0048 BF00 0000 0000 0000 00CD .....H..........
00000040: 8048 656C 6C6F 0A .Hello.
~
> hello
Hello
I'm wondering if it wouldn't be more fun to implement the assembler in Lisp inside MOROS. Currently we just need enough instructions to use the various syscalls.