Skip to content

Commit

Permalink
add cmd/casm-inspect disasm utility
Browse files Browse the repository at this point in the history
This is a tool I made while studying the casm bytecode format.
Since making thoth disassembler work requires some extra steps,
I figured it would be handy to have a version that relies on our
assembler package and supports the exact versions of input
files that are relevant to this project.

I tried to produce the correct Cairo0 program when disassembling.
If done carefully (and with metadata provided from the compiled json file),
we can use it to test the assembler in an encode-decode style
(basically we can use the disassembler output as an assembler parser input).

Given this cairo0 source file:

```cairo
%builtins output

from starkware.cairo.common.serialize import serialize_word

func div2(x: felt) -> felt {
    return x / 2;
}

func main{output_ptr: felt*}() {
    alloc_locals;
    local x = 42;
    local y = x + 1;
    local z = div2(x);
    if (y == 0) {
      serialize_word(z);
    } else {
      serialize_word(y);
    }
    ret;
}
```

And a compiled casm bytecode produced from it (output.json), we can disassemble it into the following:

```casm
// func entry pc=0
// [fp-3] => word: felt
// [fp-4] => output_ptr: felt* (implicit arg)
func starkware.cairo.common.serialize.serialize_word{output_ptr: felt*}(word: felt) {
    assert [fp-3] = [[fp-4]];
    assert [ap] = [fp-4] + 1, ap++;
    ret;
}
// func entry pc=4
// [fp-3] => x: felt
func div2(x: felt) -> felt {
    assert [ap] = [fp-3] * 1809251394333065606848661391547535052811553607665798349986546028067936010241, ap++; // div 2
    ret;
}
// func entry pc=7
// [fp-3] => output_ptr: felt* (implicit arg)
func main{output_ptr: felt*}() {
    nop; // alloc_locals; ap += 3
    assert [fp] = 42;
    assert [fp+1] = [fp] + 1;
    assert [ap] = [fp], ap++;
    call rel -10; // func div2; ap += 2
    assert [fp+2] = [ap-1];
    jmp rel 8 if [fp+1] != 0; // targets L1
    assert [ap] = [fp-3], ap++;
    assert [ap] = [fp+2], ap++;
    call rel -21; // func starkware.cairo.common.serialize.serialize_word; ap += 2
    jmp rel 6; // targets L3
  L1:
    assert [ap] = [fp-3], ap++;
    assert [ap] = [fp+1], ap++;
    call rel -27; // func starkware.cairo.common.serialize.serialize_word; ap += 2
  L3:
    ret;
}
```

This disassembler annotates some lines with recognized patterns like division operations.
It does not include any hints-related information (yet?)
  • Loading branch information
quasilyte committed Jan 17, 2024
1 parent 06dca18 commit 83beaaa
Show file tree
Hide file tree
Showing 2 changed files with 606 additions and 0 deletions.
Loading

0 comments on commit 83beaaa

Please sign in to comment.