07/04/17 00:19:47
ちょっと.code16モードで生成されるコードに疑問があるので質問させてください。
__asm__(".text\n.code16\n.global _start\n_start:\njmp boot_main\n");
void asm_putc_ng(char c) { __asm__("int $0x10" :: "a"(0x0e00|c), "b"(0x7)); }
void asm_putc_ok(char c) {
__asm__(
"mov 6(%ebp), %eax\n\t" // ココ。gccは8(%ebp)を生成するが・・・
"or $0x0e00, %ax\n\t"
"mov $0x07, %bx\n\t"
"int $0x10\n\t");
}
void boot_main(void) { asm_putc_ok('D'); asm_putc_ng('D'); }
BIOSコールで文字を出力するサンプルですが、.code16モードだと
引数のスタック上位置の計算がおかしく、引数が正常に渡りません。
こんなコードが生成されます:
asm_putc_ok: ! asm_putc_ng でも同様のプリアンブルを生成
pushl %ebp
movl %esp, %ebp
subl $4, %esp !char c用にスタック領域を取る
movl 8(%ebp), %eax !第一引数をEAXに入れようとしてるがオフセットおかしくない?
movb %al, -4(%ebp) !charなんでALだけ領域に書けば十分
リターンアドレスは16bitなので、ここは8(%ebp)でなく、6(%ebp)が
正しくないでしょうか?実際、それだと指定の文字を正しく出力します。
しかし、超メジャーなx86 gccでバグがあるとも思えないので、私が
単に16bitコード生成のための何かをしていないのではと悩んでます。
どうすれば正しいコードを生成させられるでしょうか?