私は Forth の内部インタープリターを作成していて、最も単純な部分で行き詰まっています。Mac で NASM を使用する (マッチョ)
msg db "k thx bye",0xA ; string with carriage return
len equ $ - msg ; string length in bytes
xt_test:
dw xt_bye ; <- SI Starts Here
dw 0
db 3,'bye'
xt_bye dw $+2 ; <- Should point to...
push dword len ; <-- code here
push dword msg ; <--- but it never gets here
push dword 1
mov eax, 0x4 ; print the msg
int 80h
add esp, 12
push dword 0
mov eax, 0x1 ; exit(0)
int 80h
_main:
mov si,xt_test ; si points to the first xt
lodsw ; ax now points to the CFA of the first word, si to the next word
mov di,ax
jmp [di] ; jmp to address in CFA (Here's the segfault)
実行すると、Segmentation Fault: 11 が発生します。テストとして、_main を次のように変更できます。
_main:
mov di,xt_bye+2
jmp di
そしてそれは動作します
編集 - そこにはいくつかの赤いニシンがあると思うので、これが私がやろうとしていることの最も単純な形です:)
a dw b
b dw c
c jmp _my_actual_code
_main:
mov si,a
lodsw
mov di,ax
jmp [di]
編集 - バイナリを 16 進ダンプした後、上記の b の値が実際には、ラベル c がコンパイルされたアドレスよりも 0x1000 高いことがわかります。c は 0x00000f43 ですが、b には 0x1f40 が含まれています