2009年7月3日金曜日

GCC拡張インラインアセンブラ

ちょっと今回は番外編。
ここまで見てきたソースの中でよく出くわすのがインラインアセンブラ。基本的にはasm("~アセンブラ~")という記述なのですが、カーネルで出てくるのはGCCの拡張インラインアセンブラといわれるもので、ごく普通のGAS形式のアセンブラともまたちょっと違うので読みにくさが増しています。

そこで参考にしたのが下記のサイトです。
GCC Inline Assembler

例えば前回見た「get_edd_info」には下記のようなインラインアセンブラがあります。


asm("pushfl; stc; int $0x13; setc %%al; popfl"
    : "+a" (ax), "+b" (bx), "=c" (cx), "+d" (dx)
    : : "esi", "edi");



これを整理してみると、、、

(アセンブラコード)
pushfl   フラグ退避
stc    キャリーフラグセット
int 0x13  BIOS interrupt call 
setc AL  キャリーフラグをALに格納
popfl   フラグをポップ

(出力オペランド)
ax 入出力で使う
bx 入出力で使う
cx 出力で使う
dx 入出力で使う

(入力オペランド)
指定なし

(壊れるレジスタ)
esi
edi

関数の先頭でax=0x4100、bx=0x55aa、dx=ドライブ番号と指定しています。この3つはいずれも「入出力」として指定されていることに注目。ax, bx, dxにこれらの値を入れてint 0x13を実行するとdxで指定したドライブのEDD情報を取得する、という命令になります。

0 件のコメント:

コメントを投稿