昨日は喜びのあまりメインと実行結果写真だけでしたが、今日はメインに行くまでを。
スタートアップとローダスクリプトはここを参考にさせていただきました。
アセンブラのスタートアップ
; H8/3052 Startup for GCC
.h8300h
; ベクタ設定。割込は未使用なのでリセットのみ(手抜) .section .vector .data.l _start
.section .text .global _start _start: mov.l #__stack,sp
; 初期値付データをROMからRAMへコピー mov.l #___init_data_top,er0 mov.l #___data_top,er1 1: mov.b @er0,r2l mov.b r2l,@er1 adds #1,er0 adds #1,er1 cmp.l #___data_end,er1 blo 1b
; 初期値なしデータ・BSSセクションを0でクリア。 mov.l #0,er0 mov.l #___bss_top,er1 1: mov.b r0l,@er1 adds #1,er1 cmp.l #___bss_end,er1 blo 1b
; Cのmainへ
jsr @_main
1:
bra 1b
.section .stack .global __stack __stack: |
ローダスクリプト
OUTPUT_FORMAT("coff-h8300") OUTPUT_ARCH(h8300h) ENTRY("_start")
MEMORY { vector(r): o = 0x00000000, l = 0x00000100 rom(rx): o = 0x00000100, l = 0x0007ff00 ram(rwx): o = 0x00ffdf10, l = 0x00002000 exram(rwx): o = 0x00220000, l = 0x00020000 }
SECTIONS { .vector : { *(.vector) } > vector .text : { *(.text) *(.rodata) ___init_data_top = .; } > rom
.data : AT(___init_data_top) { ___data_top = .; *(.data) ___data_end = .; } > ram
.bss ALIGN(0x10) : { ___bss_top = .; *(.bss) *(COMMON) ___bss_end = .; } > ram
.stack 0x00ffff10 : { *(.stack) } } |
簡単に説明すると、電源ONでCPUはベクタテーブルの先頭(0番地)からPCの値を読み込んで
そこから実行を開始します。このスタートアップだと_startのところです。
_startでは、スタックの設定をした後静的変数の初期化を行いCのmainを呼び出します。
mainから返ってくることは想定していませんが、返ってきちゃったら永久ループです。
尚、スタートアップ・ローダスクリプトともに極力短く書くようにしました。正直なところスタート
アップの静的変数初期化はいらないだろうと思ったんですが、mainに来るまでにはこんなこと
が行われてますよってのがわかるのもいいかなと。
でも、このスタートアップではライブラリの初期化を行っていないのでCの標準ライブラリは
使えません(初期化が必要ないものは利用可能と思われますが)。