Last Update: "2014/01/30 10:23:29 makoto"
使い方
h8300-elf-gcc を
bootstrap や pkg_add
などとして環境を構築した後の使い方についてです。
準備
使い方なので
「特権で使う」は不要で、通常の Cygwin terminal で操作します。
(なお、ここでの説明は cygwin には限りません。どの OS でも同じように
操作出来ます)
H8/300 Cross の画面にあった説明
のようにコンパイラを用意すると、次のようなものが設置されます。
gcc:
/usr/pkg/bin/h8300-elf-c++
/usr/pkg/bin/h8300-elf-cpp
/usr/pkg/bin/h8300-elf-g++
/usr/pkg/bin/h8300-elf-gcc
/usr/pkg/bin/h8300-elf-gccbug
/usr/pkg/bin/h8300-elf-gcov
/usr/pkg/cross-h8300-elf/bin/h8300-elf-c++
/usr/pkg/cross-h8300-elf/bin/h8300-elf-cpp
/usr/pkg/cross-h8300-elf/bin/h8300-elf-g++
/usr/pkg/cross-h8300-elf/bin/h8300-elf-gcc
/usr/pkg/cross-h8300-elf/bin/h8300-elf-gcc-3.4.6
/usr/pkg/cross-h8300-elf/bin/h8300-elf-gccbug
/usr/pkg/cross-h8300-elf/bin/h8300-elf-gcov
binutils:
% pkg_info -qL cross-h8300-elf-binutils |grep pkg/bin/
/usr/pkg/bin/h8300-elf-addr2line
/usr/pkg/bin/h8300-elf-ar
/usr/pkg/bin/h8300-elf-as
/usr/pkg/bin/h8300-elf-c++filt
/usr/pkg/bin/h8300-elf-gprof
/usr/pkg/bin/h8300-elf-ld
/usr/pkg/bin/h8300-elf-nm
/usr/pkg/bin/h8300-elf-objcopy
/usr/pkg/bin/h8300-elf-objdump
/usr/pkg/bin/h8300-elf-ranlib
/usr/pkg/bin/h8300-elf-readelf
/usr/pkg/bin/h8300-elf-size
/usr/pkg/bin/h8300-elf-strings
/usr/pkg/bin/h8300-elf-strip
上記を気持よく使うには、PATH 環境変数を設定します。
例えば
% export PATH=/usr/pkg/bin:${PATH}
とします。これは pkgsrc で用意したものを使う時の一般的な設定なので、
既に設定済であれば不要です。
gcc
次に、例えば c の記述を hello.c という名前で用意して
#include
main (){
static char hello[] = "Hello World!";
printf("%s\n", hello);
}
これで
% h8300-elf-gcc hello.c
とします。これで a.out が出来るはずです。結構大きいです。
as
アセンブラは as ですが、GNU のものなので gas ということもあります。
% h8300-elf-gcc -S hello.c
とすると hello.s を作ります。人間も一応読めるアセンブリ(言語)で書いてあります。
これをアセンブルするには、例えば次のようにします。
-al は結果のリストを表示するためで、なくても a.out を作ります。
% h8300-elf-as -al hello.s
Renesas H8/300 GAS hello.s page 1
1 .file "hello.c"
2 .section .data
3 .type hello___0, @object
4 .size hello___0, 13
5 hello___0:
6 0000 48656C6C .string "Hello World!"
6 6F20576F
6 726C6421
6 00
7 .section .rodata
8 .LC0:
9 0000 25730A00 .string "%s\n"
10 .section .text
11 .align 1
12 .global _main
13 _main:
14 0000 6DF6 mov.w r6,@-r7
15 0002 0D76 mov.w r7,r6
16 0004 79020000 mov.w #hello___0,r2
17 0008 6DF2 mov.w r2,@-r7
18 000a 79020000 mov.w #.LC0,r2
19 000e 6DF2 mov.w r2,@-r7
20 0010 5E000000 jsr @_printf
21 0014 0B87 adds #2,r7
22 0016 0B87 adds #2,r7
23 0018 0D20 mov.w r2,r0
24 001a 6D76 mov.w @r7+,r6
25 001c 5470 rts
26 .size _main, .-_main
27 .end
objdump
この
objdump
も、次の
objcopy
も
--help だけを付けて起動すると、
使い方の簡単な説明を表示します。また処理対象を省略すると a.out と解釈します。
そこで、次の -h はへッダというか中身の一覧を表示します。
% h8300-elf-objdump -h
a.out: file format elf32-h8300
Sections:
Idx Name Size VMA LMA File off Algn
0 .text 0000001e 00000000 00000000 00000034 2**1
CONTENTS, ALLOC, LOAD, RELOC, READONLY, CODE
1 .data 0000000d 00000000 00000000 00000052 2**0
CONTENTS, ALLOC, LOAD, DATA
2 .bss 00000000 00000000 00000000 0000005f 2**0
ALLOC
3 .rodata 00000004 00000000 00000000 0000005f 2**0
CONTENTS, ALLOC, LOAD, READONLY, DATA
-s は中身を表示しますが、上の中で .text セクションだけを見るとすると -j .text も付けると便利です。
% h8300-elf-objdump -j .text -s
a.out: file format elf32-h8300
Contents of section .text:
0000 6df60d76 79020000 6df27902 00006df2 m..vy...m.y...m.
0010 5e000000 0b870b87 0d206d76 5470 ^........ mvTp
ここに見えている数値は、上のリスト出力の 14 行目から 25
行目に表示されている機械語の部分と同じことが確認出来ますでしょうか (左端の 0000 と 0010 はアドレスです)。
この他 objdump -d の逆アセンブルも使うことがありますが、今回はあまり関係ないので、
説明は省略します。
objcopy
実は、次のようにすると、verilog の二進の文字形式に変換します。
% h8300-elf-objcopy --input-target elf32-h8300 --output-target verilog a.out verilog
objcopy で利用出来る target の形式は
h8300-elf-objcopy --help の最後に表示されます。
% h8300-elf-objcopy --help |& tail -5
-V --version Display this program's version number
-h --help Display this output
--info List object formats & architectures supported
h8300-elf-objcopy: supported targets: elf32-h8300 elf32-little
elf32-big srec symbolsrec verilog tekhex binary ihex
Report bugs to
上に示した方法だと、a.out の全てを変換してしまうので -j .text を付けます。
% h8300-elf-objcopy -j .text \
--input-target elf32-h8300 --output-target verilog a.out verilog
上記は elf32-h8300 形式の a.out を verilog 形式の verilog に変換する、という指定です。
ここまでのまとめ。次のようにすると verilog 形式を生成します。
h8300-elf-gcc -S hello.c ;
h8300-elf-as -al hello.s ;
h8300-elf-objcopy -j .text --input-target elf32-h8300 \
--output-target verilog a.out verilog
出来た verilog の中身を見てみます。
modena@makoto 16:22:44/140128(~/c)% cat verilog
@00000000
6D F6 0D 76 79 02 00 00 6D F2 79 02 00 00 6D F2
5E 00 00 00 0B 87 0B 87 0D 20 6D 76 54 70
ld
ただし、実は、すぐ上の「まとめ」で示した方法だと、
リンカ (ld)の処理を省略しているので、
機械語の中の未解決の参照が 00 00 のままになっていたりします。
ここから先は、生成した機械語を、
どのような実機(実行環境)で動かすことを想定しているか、
にもよりますので、話が一段と長くなります。
そこで、とりあえずは、ここまでとします。
ちなみに、h8300-elf-gcc hello.c
とした時などで生成する機械語は elf 形式が読める (実行出来る) 環境を想定しています。
elf とは Executable and Linking Format の意味で、
実行のために必要な、いろいろな情報が付加されています。
これも一段と先が長い話になります。
以前は a.out 形式というものがあって、
最近は、それとは違う elf
形式が使われるようになったのですが、
今は elf 形式になっていても、
指定を省略した時の出力(や入力の)ファイル名は a.out になっています。
readelf
ELF の中身を見るのに、次のような方法もあります。
modena@makoto 08:30:18/140130(~/c)% h8300-elf-readelf -h a.out
ELF Header:
Magic: 7f 45 4c 46 01 02 01 00 00 00 00 00 00 00 00 00
Class: ELF32
Data: 2's complement, big endian
Version: 1 (current)
OS/ABI: UNIX - System V
ABI Version: 0
Type: REL (Relocatable file)
Machine: Renesas H8/300
Version: 0x1
Entry point address: 0x0
Start of program headers: 0 (bytes into file)
Start of section headers: 156 (bytes into file)
Flags: 0x800000
Size of this header: 52 (bytes)
Size of program headers: 0 (bytes)
Number of program headers: 0
Size of section headers: 40 (bytes)
Number of section headers: 9
Section header string table index: 6
蛇足
ついでに、更に蛇足を加えますと、ここでは次の二つの方法を混ぜて説明しています。
- (全自動)
gcc filename.c として a.out を直接生成する (cc1 as ld を内部で呼出す)
- (手動)
gcc -S filename.c で filename.s を生成し as を使って a.out を生成する
普通の PC (OS) などでは前者を使いますが、組込用や、しくみを理解するには
後者を使います。
もう一つ加えますと gcc は、
引数に応じて cc1 as ld のどれが必要なのかを判断して、
その各部分だけの処理も行なうようになっています。
cc1 とは gcc が呼び出す、せまい意味の c コンパイラです。
実はここの情報を用意する前には、
「h8300-hms と h8300-elf の二つがあって、これは何だろう」
と思っていました
hms | Hitachi Micro System |
binutils-2.17 まで (だけ)利用出来る。
| elf | Executable and Linking Format |
|
|