aboutsummaryrefslogtreecommitdiffhomepage
path: root/README.md
blob: fc5e8a711f35a320d03b6120dd81f0b923889fba (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# juicebox-asm

[![Rust][wf-badge]][wf-output] [![Rustdoc][doc-badge]][doc-html]

[wf-output]: https://github.com/johannst/juicebox-asm/actions/workflows/tests.yml
[wf-badge]: https://github.com/johannst/juicebox-asm/actions/workflows/tests.yml/badge.svg
[doc-html]: https://johannst.github.io/juicebox-asm
[doc-badge]: https://img.shields.io/badge/juicebox__asm-rustdoc-blue.svg?style=flat&logo=rust

An `x64` jit assembler for learning purpose with the following two main goals:

- Learn about x64 instruction encoding.
- Learn how to use the rust type system to disallow invalid operands.

## Example

```rust
use juicebox_asm::insn::*;
use juicebox_asm::Runtime;
use juicebox_asm::{Asm, Imm32, Label, Reg32::*};

fn main() {
    let mut asm = Asm::new();

    // Reference implementation
    //   int ret = 0;
    //   int n   = 42;
    //
    // loop:
    //   ret += n;
    //   --n;
    //   if (n != 0) goto loop;
    //
    //   return;

    let mut lp = Label::new();

    asm.mov(eax, Imm32::from(0));
    asm.mov(ecx, Imm32::from(42));

    asm.bind(&mut lp);
    asm.add(eax, ecx);
    asm.dec(ecx);
    asm.test(ecx, ecx);
    asm.jnz(&mut lp);

    asm.ret();

    let mut rt = Runtime::new();
    let func = unsafe { rt.add_code::<extern "C" fn() -> u32>(&asm.into_code()) };
    assert_eq!(func(), (0..=42).into_iter().sum());
}
```

The [`examples/`](examples/) folder provides additional examples:

- [`fib.rs`](examples/fib.rs) jit compiles a function to compute the
  `fibonacci` sequence.
- [`add.rs`](examples/add.rs) jit compiles a function calling another function
  compiled into the example binary.
- [`tiny_vm.rs`](examples/tiny_vm.rs) defines a minimal `virtual machine (VM)`
  with registers, instructions, data & instruction memory. The VM demonstrates
  a simple *jit compiler* which has a *jit cache* and translates each *basic
  block* on first execution when running a VM guest image. For reference an
  interepter is also implemented.
- [`bf.rs`](examples/bf.rs) implements a
  [brainfuck](https://en.wikipedia.org/wiki/Brainfuck) jit compiler
  and interpreter.

## git hook for local development

The [`ci/`](ci) checks can be run automatically during local development by
installing the following `pre-commit` git hook.
```sh
echo 'make -C ci' > .git/hooks/pre-commit
chmod +x .git/hooks/pre-commit
```

## License
This project is licensed under the [MIT](LICENSE) license.