リンカに渡す順番を変えてプログラムの配置を変えてみる
#gcc #linker #CPU実験
リンカに渡すプログラムの順番を変えることで実行ファイル中のプログラムの配置が変わることを確認したい。以下のソースファイル の(A)と(B)の順番を変えて実行結果が変わることを確認する。
ソースファイル (A)
code:a.s
addi x1, x0, 10
ソースファイル(B)
code:b.s
addi x2, x1, 10
A→Bの順番で実行されるようにビルド
リロケータブルオブジェクト(*.o)を生成。
code:sh
$ riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -c a.s
$ riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -c b.s
リロケータブルオブジェクト(*.o)から実行ファイル(a.out)を生成。
code:sh
$ riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -Wl,-Ttext=0x00 -nostdlib -o a.out a.o b.o
実行ファイル(a.out)を逆アセンブルして中身を確認。
a.s と b.s がコンパイルされた結果が .text セクションに格納されていて、(A)→(B)の順番で命令が格納されている。
code:sh
$ riscv64-unknown-elf-objdump -D a.out
a.out: file format elf32-littleriscv
Disassembly of section .text:
00000000 <__BSS_END__-0x1008>:
0: 00a00093 li ra,10 (== addi x1, x0, 10 となる)
4: 00a08113 addi sp,ra,10 ( == addi x2, x1, 10 となる)
Disassembly of section .riscv.attributes:
00000000 <.riscv.attributes>:
...
機械語だけが入ったバイナリデータ(a.rom)を生成。
code:bash
$ riscv64-unknown-elf-objcopy -O binary a.out a.rom
実行
実行してみる。以下の実行結果になればOK。
x1 = 10
x2 = 20
code:sh
$ ruby rv32sim.rb sample/a.rom
--------------------------------------------------------------------------------
x00 = 0x0 (0) x01 = 0xa (10) x02 = 0x14 (20) x03 = 0x0 (0)
x04 = 0x0 (0) x05 = 0x0 (0) x06 = 0x0 (0) x07 = 0x0 (0)
...
B→Aの順番で実行されるようにビルド
今度はB→Aのように実行されるようにビルド。*.o ファイルはすでに生成されているのでリンクだけ。
code:sh
$ riscv64-unknown-elf-gcc -march=rv32i -mabi=ilp32 -Wl,-Ttext=0x00 -nostdlib -o a.out b.o a.o
実行ファイル(a.out)を逆アセンブルして中身を確認。
a.s と b.s がコンパイルされた結果が .text セクションに格納されていて、(B)→(A)の順番で命令が格納されている。
code:sh
$ riscv64-unknown-elf-objdump -D a.out
a.out: file format elf32-littleriscv
Disassembly of section .text:
00000000 <__BSS_END__-0x1008>:
0: 00a08113 addi sp,ra,10
4: 00a00093 li ra,10
Disassembly of section .riscv.attributes:
00000000 <.riscv.attributes>:
...
再度、機械語だけが入ったバイナリデータ(a.rom)を生成。
code:bash
$ riscv64-unknown-elf-objcopy -O binary a.out a.rom
実行
実行してみる。B→Aの順に実行されて、以下の実行結果になる。
x1 = 10
x2 = 10
code:sh
$ ruby rv32sim.rb sample/a.rom
--------------------------------------------------------------------------------
x00 = 0x0 (0) x01 = 0xa (10) x02 = 0x14 (20) x03 = 0x0 (0)
x04 = 0x0 (0) x05 = 0x0 (0) x06 = 0x0 (0) x07 = 0x0 (0)
...
以下メモ。
逆アセンブル
生成したオブジェクトファイルを逆アセンブル。
code:sh
$ riscv64-unknown-elf-objdump -D a.o
$ riscv64-unknown-elf-objdump -D b.o
生成した実行ファイルを逆アセンブル。
code:sh
$ riscv64-unknown-elf-objdump -D a.out
gccのオプション
-c オプション
-c Compile and assemble, but do not link.
参考
コンパイラの構造
https://www.gadgety.net/shin/tips/unix/compiler.html