C言語からのアセンブリの関数呼び出し(引数あり)

Cで関数を呼び出すと、第一引数から[ESP+4][ESP+8][ESP+12][ESP+16]に入るので、アセンブリではここから値を取り出す。

Cを使う場合は自由に使えるレジスタはEAX ECX EDXの3つだけ。

ポインタの説明は飛ばす。

前処理用Makefile追加

著者作ツールを使わないための前処理が面倒になってきたのでMakefileに追記した。

1
2
3
4
5
pre:
nkf --overwrite *.nas *.c
sed -i s/0x7dfe-\\$$/0x01fe-\(\\$$\-\\$$\\$$\)/ $(IPL_NAME).nas
sed -i s/_io_/io_/g $(NASK_FUNC).nas
sed -i s/^\\[/\;\\[/ *.nas

make preで今までやってた前処理ができる。os.ldMakefileを次のディレクトリにコピーすれば良い。

新出アセンブリ

命令
PUSHFD push flags double-word. スタックにpushする。
POPFD pop flags double-word. スタックからpopしてEFLAGSに設定する。
POP スタックからpopする。
PUSH スタックにpushする。
CLI 割り込み許可フラグを0にする
STI 割り込み許可フラグを1にする
IN デバイスから信号を受け取る
OUT デバイスに信号を送る

EFLAGSからEAXに直接読み込めないので、スタックを介す必要がある。

EFLAGSの構造

15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
NT IOPL OF DF IF TF SF ZF AF PF CF

(IOPLは12/13で一つの扱い)

また、RET時にEAXに入っていたものが関数の返り値とみなされる。

パレットの色変更

  1. 割り込みが入らないようにCLIする。
  2. 0x03c8に設定したいパレット番号を書き、RGBの順に0x03c9に書き込む。次のパレットも続けて設定するときは、パレット番号を省略して続けて0x03c9に書き込む。
  3. 読み出すときは1と同様に、0x03c7 0x03c9を使用する。
  4. STIする。
1
io_out8(0x03c9, rgb[0] / 4);

set_paletteで割る4しているのはVGAのパレットがRGBそれぞれ6bitつまり64階調しかないからである。色を定義するときにはわかりやすい8bitを使い、設定時に8bitRGBを6bitRGBで近似している。8bitなのはパレットの数である。

VGA 【 Video Graphics Array 】
オリジナルのVGAは同社が1987年に発売したPS/2に初めて搭載したディスプレイ表示用の専用ICチップおよびその仕様を指し、256KBのVRAM(ビデオメモリ)を内蔵し最高で横640×縦480ピクセル、262,144色(RGB各6ビットの18ビット)から指定した16色を同時発色できる能力があった。
http://e-words.jp/w/VGA.html

Video Graphics Array
640×480ドット16色および320×200ドット256色モードは完全に再定義可能なパレットを持ち、それぞれ18ビット(262,144色)のRGBテーブルから色を選択する。
https://ja.wikipedia.org/wiki/Video_Graphics_Array

画面を書く

長方形を塗りつぶしていくだけ。VRAMにパレット番号を入れるとその色で描画される。

Windows10風。我ながら頑張った。

めっちゃ似てる!?

参考文献