gforth で assembler
Forth
2022-9-26 1:46 JST

gforth には assembler 機能がついているのでそれを使ってみる。

amd64

まずは ubuntu で最新の gforth をコンパイル。Gforth 0.7.9_20220916 となっている。GFORTHPATH を設定して gofroth を実行。arch/amd64/testasm.fs の一部を試す。assembler とするところが味噌。

assembler   ok
abi-code my-f+  ok 1
    SP passed in di, returned in ax,  address of FP passed in si  ok 1
   si )  ax mov             load FP into ax  ok 1
   8 ax d)  dx lea          computed resulting FP in dx  ok 1
   ax )  xmm0 movsd         load floating point TOS into xmm0  ok 1
   dx )  xmm0 addsd         added from NOS to xmm0  ok 1
   xmm0 dx )  movsd         write TOS to FP stack  ok 1
   dx  si ) mov             write resulting FP back  ok 1
   di ax mov                return SP unchanged  ok 1
   ret  ok 1
end-code  ok

0  ok 1
s>f  ok f:1
1  ok 1 f:1
s>f  ok f:2
my-f+  ok f:1

abi-codeを使うとそのままコードをワードに埋め込める。もっと簡単な例があったんだけど、見失った。

amd64 直書き

実はコロンでの登録でなくても直接コードを書くとデータ領域(allot で獲得される領域)にアセンブラコードが書かれる。

assembler   ok
here  ok 1
.d lods  ok 1
.d ax ) jmp  ok 1
16 dump
7F2916441140: AD FF 20 00  00 00 00 00 - 00 00 00 00  00 00 00 00  
 ok

8086

いまさら 8086 でもないだろうがこれも include すればアセンブラをデータ領域に書いてくれる。本当は com まで作ってくれる。と言いたいところだが、8086.com というファイルは出来たものの動かなかった。

Gforth EC 8086 doesn't build で 4 Oct 2017 に指摘されているが、そのまま放置してあるみたいね。kernel-ec って embedded cross の意味だったのか。build-ec ってコマンドまであるのに。

include arch/8086/asm.fs
  ' di Alias w  ok
  system depending macros  ok
  : next,  compiled
    lods,  compiled
    ax w xchg,  compiled
    w ) jmp, ;  ok

使いみちがよくわからんが next, は登録できた。amd64 で実行すると死ぬと思うけど。

arm

32bit の arm もある。64bit は asm.fs なかった。

include arch/arm/asm.fs

assembler
CODE mydrop  ok 1
   R9   R9 4 #      ADD,  ok 1
   NEXT,  ok 1
END-CODE  ok
here  ok 1
R9 R9 4 # ADD,  ok 1
8 dump
7F0733190054: 04 90 89 E2  00 00 00 00 -                           ........
 ok

未確認だが t,

arm の asm.fs をみてたら t, などの記述を見つけた。統一していないみたいで amd64 とかは , を直接使っている(ように見える)。

 change these for cross compilation
: there  here ;
: t@  ul@ ;
: t!  l! ;
: t,  here 4 allot t! ;

あ〜でも cross.fs で上書きしているみたいにも見えるなぁ。どうやら there という名称じゃなくて T でターゲット環境に切り替えて here を評価しているみたいだから、ターゲット環境の here に書き込むみたいだな。there もあるのか。

: here  ( -- there )    there ;
: allot ( n -- )        tdp +! ;
: ,     ( w -- )        T here H tcell T allot  ! H ;

どうやら cross.fs を読み込むとその環境を使えるようになるみたいね。

include cross.fs
order Cross Forth Target Forth Root     Target  ok