🌊

AssemblyでもWebAssemblyを書きたい

に公開

はじめに

Assembly (以下アセンブリ)でも WebAssembly (以下 Wasm) を書きたいと思ったのですが、そのようなツールは調べた限りありませんでした。
そのため自分でアセンブリから Wasm を書くツールを作ろうと思いました。
と思っていたのですが意外と難航していたので Cursor という AI エディタの力を使って作成しました。

作成したツール

https://github.com/famasoon/asm2wasm

Assembly という名を冠している WebAssembly を果たしてアセンブリで書けるのかという疑問を解消するために作成しました。

C++ を使用して x86 アセンブリから Wasm を生成するコードを作成しました。

とは言うものの、アセンブリを素直に解析してくれる基盤はなかなか見つからなかったです。
リフターというものを使用すればアセンブリを解析できますが、リフターはいまのところバイナリファイルの対応をしているものばかりで、asmコードを解析するものは私が調べた限り見つかりませんでした。

仕方がないので簡易的なアセンブリのパーサと、パースしたアセンブリの命令をLLVM IRに変換するコードを書き、そこからさらに Wasm に変換するコードを書きました。

asm2wasm/build on  master [?] via △ v3.28.3 
❯ cat ../examples/simple_add.asm           
start:
    mov %eax, 10
    mov %ebx, 20
    add %eax, %ebx
    ret

asm2wasm/build on  master via △ v3.28.3 
❯ ./asm2wasm ../examples/simple_add.asm         
Output files are not specified, using ../examples/simple_add.wasm and ../examples/simple_add.wat
Parsing Assembly file: ../examples/simple_add.asm
Outputting WebAssembly binary: ../examples/simple_add.wasm
Outputting WebAssembly text: ../examples/simple_add.wat
Generated WebAssembly text:
----------------------------------------
(module
  (memory 1 65536)
  (func $start (result i32) (local $0 i32) (local $1 i32) (local $2 i32) (local $3 i32) (local $4 i32) (local $5 i32) (local $6 i32) (local $7 i32)
    local.get 1
    i32.const 10
    i32.store
    local.get 0
    i32.const 20
    i32.store
    local.get 1
    i32.load
    local.set 2
    local.get 0
    i32.load
    local.set 3
    local.get 2
    local.get 3
    i32.add
    local.set 6
    local.get 1
    local.get 6
    i32.store
    local.get 1
    i32.load
    local.set 4
    local.get 4
    return
  )
)
----------------------------------------
WebAssembly conversion completed.

シンプルに加算を行う start 関数を Wasm に変換しています。
まだまだバグだらけ、最適化できそうな箇所も多く残っていますが、アセンブリから Wasm を生成できることが確認できました。

Cursor での開発

Cursor での開発はとても便利でした。
特に AI エディタの力を借りることで、LLVM IR の生成を自動で行ってくれました。
これといったコンテキストエンジニアリングもしていません。
エラーや最適化できそうな箇所を見つけたら都度修正するようにエージェントに指示を出していったら、あっという間に修正が完了しました。

まとめ

アセンブリから Wasm を生成するツールを作成しました。
ですが、かなりしんどいので C/Zig/Tiny Go なりで Wasm を書く方が楽だと思います。

GitHubで編集を提案

Discussion