moros icon indicating copy to clipboard operation
moros copied to clipboard

Add assembler and disassembler commands

Open vinc opened this issue 1 year ago • 5 comments

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

vinc avatar Nov 22 '23 23:11 vinc

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

vinc avatar Nov 22 '23 23:11 vinc

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

vinc avatar Nov 23 '23 07:11 vinc

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.

vinc avatar Nov 23 '23 18:11 vinc

~
> 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

vinc avatar Nov 23 '23 22:11 vinc

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.

vinc avatar Nov 24 '23 18:11 vinc