2008年7月4日

 printf()相当の関数を使ってCOM1にログをはいてます。
 関数のトレースログに引数も一緒に表示しようと以下のようにしてみました。

void hoge(WORD arg1, WORD arg2, DWORD arg3)
{
  logprintf("arg1 = %x, arg2 = %x, arg3 = %x\n"
        , arg1, arg2, arg3);
    :
}

 たいていのprintfはサイズ指定フラグを指示しなくてもちゃんとやってくれるので書きませんでした。
 でも出てきた結果は想像と違いました。arg1に0x1234、arg2に0x5678、arg3に0x9ABCDEF0が入っていたとしたとき、出てきた結果は以下のようなものでした。

arg1 = 0x56781234, arg2 = 0x9ABCDEF0, arg3 = 0x00000000

 ぶwwwwつまっとるwwwww
 確かに理屈の上では...でとった引数は割りと無秩序にスタックに積まれるはずですから、PCなんかで試してみれば32bitアラインメントの都合で32bitごとに積んでいって問題なく表示するんでしょうが、ターゲットが16bitアラインメントなので16bitの変数はそのまま並べちゃったんですね。でも量指定フラグがなくてint相当の幅として扱ったので上記の結果と。
 理屈がわかれば対応は簡単、量指定フラグを付け足してやりましょう。

void hoge(WORD arg1, WORD arg2, DWORD arg3)
{
  logprintf("arg1 = %hx, arg2 = %hx, arg3 = %x\n"
        , arg1, arg2, arg3);
    :
}

 表示しない……orz
 関数仕様 (と言うかヘッダコメント) を読んでみた感じどうも量指定フラグには対応してないようです。どないせいと。
 しかしそこは自称紙一重のこちら側な長月、すぐさま思いつきました。%xが32bitとるなら32bitな型にキャストしてやればよい。

void hoge(WORD arg1, WORD arg2, DWORD arg3)
{
  logprintf("arg1 = %4x, arg2 = %4x, arg3 = %x\n"
        , (DWORD)arg1, (DWORD)arg2, arg3);
    :
}
arg1 = 0x1234, arg2 = 0x5678, arg3 = 0x9ABCDEF0

 表示もちゃんとできました。お疲れ様でした。
 でもこんなコード書かなきゃいけない環境に涙目です。スタックにできた合計32bitの隙間も微妙にもったいないです。と言うかアセンブリレベルで考えたときにロードとストアの効率が半分です。もったいないもったいない……。

 と言うわけでぷるぐらみんぐネタに見せかけた日記でした。

posted @ 11:25 | Feedback (2)