またお前か!!
far call を修正して、再度、チャレンジ!!
結果 → 動いた!! と思ったら、固まった... orz
はい、トレース、トレース。<これ重要!!
とりあえず、"TEST!!"は、表示されている。
その後、プロンプトが戻ってこない。
またまたソースを晒しながら、追ってみましょう。
; ファンクションコール設定 MOV word [0x21*4+0], int0x21entry MOV word [0x21*4+2], 0x0000
割り込みベクタ設定部です。
微妙に書き方が変な気もしますが、とりあえず、エラーは出ていない。(笑)
; ; ファンクションコール エントリー ; int0x21entry: CMP AH, 0x09 JZ int0x21puts JMP int0x21end int0x21puts: CALL puts int0x21end: IRET
エントリー部は、とりあえず、こんな感じ。
DOSのファンクションコールに倣って、文字列出力は、AH=0x09とした。
まだ、一つしかファンクションがないけど、これまた、とりあえず。
CALL puts は、セグメント内コールになっているけど、
割り込みベクタの設定で、CS=0x0000になっているから、問題ないはず。
puts の中身については、これまで通り。
とりあえず、文字列が表示されている事を考えると、puts の呼び出しはOKっぽい。
その次の命令は、IRETだから、ただ戻るだけ。
で、割り込みから復帰した、次の命令は、RETFだから、これも、ただ戻るだけだな。
う〜む。
そうすると、手続き呼び出しコマンドに戻るわけだけど、その次の命令は、
; 一応、改行しておく CALL putcrlf
これが落ちてる?何故?
・・・・・・(考え中)
そう言えば、前にも、こんな事がなかったっけ?
手入力した手続きは、セグメント0x1000に配置する前提で、
ファンクションコール直前にDSレジスタを変更している!!
それを元に戻さないままリターンしたもんだから、DS=0x1000のままなのか!!
あひゃ!!
1E PUSH DS B80010 MOV AX, 0x1000 8ED8 MOV DS, AX B409 MOV AH, 0x09 BE[0F00] MOV SI, testmsg CD21 INT 0x21 1F POP DS CB RETF testmsg: 5445535421210D0A00 DB "TEST!!", 0x0D, 0x0A, 0x00
これで、どうだ?
結果 → 動いた!!
(でも、まだ、QEMU上でだけなんだけどね)