AT&Tアセンブリで変数を正しく見つける方法
-
11-12-2019 - |
質問
アセンブリを使用して(AT&T構文、およびGNU / GAS)を使用してブートストラップを作成することを実践しています。小さなプログラムは組み立てられてリンクされ、次に仮想ディスクの最初のセクタにコピーされます。BIOSはそれを0000:7c00
にロードし、ここで問題が発生します。call hello
は、実行中にcall 0010
からcall 7c10
に変換されます。しかし、movw $message, %as
は再配置されません。ax
はまだ0026
ではなく、7c26
です。その結果、画面にHello World
を作成できないことです。代わりに、0000:0026
のいくつかのランダムなデータが画面に表示されます。
起動中にどのように正しいものにすることができますか?ディレクティブを使用してASMソースコードを変更する必要がありますか?またはリンクスクリプトを変更する必要がありますか?
ありがとうございました!
.text
.global _start
.code16
_start:
movw %cs, %ax
movw %ax, %ds
movw %ax, %es
call hello
jmp .
.org 0x10
hello:
movw $message, %ax
movw %ax, %bp
movw $13, %cx
movw $0x1301, %ax
movw $0x000c, %bx
movb $0, %dl
int $0x10
ret
message:
.ascii "Hello, World!"
.org 0x01fe
.byte 0x55
.byte 0xaa
.
次の組み立てとリンクスクリプトを使用します
as -o boot.o boot.s
//generate object code
ld -Ttext 0x0 -e _start -s -o boot.out boot.o
//relocate .text to 0x0
//entry is _start
objcopy -O binary -j .text boot.out boot
//copy .text section to boot
vboxmanage convertfromraw boot boot.vdi --format VDI
//create vdi for virtual box
. 解決
私はあなたがあなたのコードをコンパイルしている方法にあることがわかりました。
あなたのコードの作業を得るための正しいステップは次のとおりです。
as boot.s -c -o boot.o
ld --oformat binary --Ttext 0x7C00 -o boot.bin boot.o
.
他の人が言ったように、その住所であなたのコードを再配転させるために--Ttext 0x7C00
パラメータをld
に渡すことを言ったように注意してください。
追加の提案として、このようなコードを構造化してみてください。
.text
.global _start
.code16
_start:
jmp stage1_start
...
stage1_start:
<your bootloader here>
.
これは、2バイト(最初のジャンプ命令の長さ)後にディスク記述テーブルを配置する必要があるので、これはBIOSコードがハードドライブを調べる方法に適しています。
さらに、このようなよりas
のような構文で最後の指示をリファクタリングすることができます。
. = _start + 0x0200 - 2
.short 0x0AA55
.
.
変数がロケーションカウンタである場合。このカウンタがどのように機能するかについての詳細は、 ld
ではなくas
のコンテキスト