AKI-SH2/7045用スタートアップルーチン
アセンブリソース「startup.s」

Copyright(C) 20Feb2004
coskx 

【1】スタートアップルーチンアセンブリソース「startup.s」
 このスタートアップルーチンはAKI-SH2/7045をWindowsマシンでクロスコンパイルして使用している環境で使用されているものです。

 スタートアップルーチンとは,マイコンの電源ONと同時に起動し,必要な処理を行なって,Cで記述された関数main()をcallするまでの作業を行なうプログラムです。

基本的なスタートアップルーチンの役割は
(1)スタックポインタの設定              [A]
(2)各ポート初期化                                 [B]
(3)必要なROM領域のRAM領域変数へのコピー            [C]
  (これはリンカスクリプトと連動しています)
(4)関数main()の呼び出し                              [D]
です。

これに次のものを付け加えます。
(1)マシン語でないと記述できないCPU割り込みマスク設定関数  [E]
(2)マシン語でないと記述できないCPU割り込みマスク読出関数  [F]

【2】本スタートアップルーチンの特徴
 (1)初期化されたグローバル変数,関数内static変数を,実行時にはRAMに割り当てて
    正常に動作させるようにしました。
 (2)関数main()から戻ってきても,無限ループに入るようにしました。
 (3)CPUの割り込みマスクのセット・ゲット関数をCプログラムに提供します。
   setIntMask()  割り込みマスク設定関数
   getIntMask()  割り込みマスク読出関数

【3】本スタートアップルーチンを利用した場合のプログラム中での変数の取り扱い
(1)初期化されていないグローバル変数 RAM領域
(2)初期化されたグローバル変数    RAM領域
(3)初期化された関数内static変数   RAM領域
(4)const修飾子のある初期化されたグローバル変数    ROM領域
(5)const修飾子のある初期化された関数内static変数   ROM領域
 オート変数はconst修飾語をつけてもスタック領域にセットされ,値の変更をコンパイラがチェックするだけです。(値をプログラム中で変更するとコンパイルエラーとなる。)

大きな定数表(配列)をグローバル変数で与えるときにはconst修飾子をつけるとROM領域に割り当てられ,少ないRAMしか持たないH8のRAM節約になることを意味します。(関数内で大きな定数表(配列)を与える場合はconst staticにすればよい。)

【4】スタートアップルーチン「startup.s」のソース

!*****************************************************************************
!   SH7045マイコンボード スタートアップルーチン
!                                          (C) 30Nov2003 coskx, A.YAMASHITA

!  このスタートアップで行なっていること
!  (1)スタックポインタの初期化
!  (2)マルチプレックスピンの初期化
!      (アドレスとポート共用のピンをアドレスとして使えるようにするなど)
!  (3)変数領域への初期値のコピー
!  (4)初期値を持たない変数領域のクリア(C言語の仕様にあわせる)
!  (5)main()の呼び出しと直後に無限ループの設置
!  このスタートアップルーチンファイルでのサービス関数
!  (1)void setIntMask(int mask) 割り込みマスクの設定関数
!  (2)int getIntMask(void) 割り込みマスクの読み出し関数
!  (3)__main() ダミー関数
!      これを定義しておくと予期しないライブラリ関数が付加されることがない
!*****************************************************************************
    .section    .text          ! スタートアップルーチンをROM領域に書き込み
    .global     _start         ! プログラム開始位置をエクスポート
    .extern     _dataRAM_begin
    .extern     _dataRAM_end
    .extern     _dataROM_begin
    .extern     _bss_begin
    .extern     _bss_end

_start:                                 ! プログラム開始位置
!-----------------------------------------------------------------------------
! スタックポインタ設定
!
! 汎用レジスタR0〜R15のうちR15がハードウェアスタックポインタに指定されている
! アドレスは 0xFFFFF000〜0xFFFFFFFF の内臓RAMを使用するため、
! STACK_ROOTは0x0を入れておく
!-----------------------------------------------------------------------------
    MOV.L    STACK_ROOT,    r15
!-----------------------------------------------------------------------------
! 各ポート初期化
! 秋月製のマイコンキットでは標準で外部RAMが実装されている.mode2にセットする
!-----------------------------------------------------------------------------
    MOV.L       BCR1,     r1         ! BCR1   -> r1
    MOV.W       D_BCR1,   r0         ! D_BCR1 -> r0
    MOV.W       r0,       @r1
    MOV.L       BCR2,     r1         ! BCR2   -> r1
    MOV.W       D_BCR2,   r0         ! D_BCR2 -> r0
    MOV.W       r0,       @r1
    MOV.L       WCR1,     r1         ! WCR1   -> r1
    MOV.W       D_WCR1,   r0         ! D_WCR1 -> r0
    MOV.W       r0,       @r1
    MOV.L       PACRH,    r1         ! PACRH   -> r1
    MOV.W       D_PACRH,  r0         ! D_PACRH -> r0
    MOV.W       r0,       @r1
    MOV.L       PACRL1,   r1         ! PACRL1   -> r1
    MOV.W       D_PACRL1, r0         ! D_PACRL1 -> r0
    MOV.W       r0,       @r1
    MOV.L       PBCR1,    r1         ! PBCR1   -> r1
    MOV.W       D_PBCR1,  r0         ! D_PBCR1 -> r0
    MOV.W       r0,       @r1
    MOV.L       PBCR2,    r1         ! PBCR2   -> r1
    MOV.W       D_PBCR2,  r0         ! D_PBCR2 -> r0
    MOV.W       r0,       @r1
    MOV.L       PCCR,     r1         ! PCCR   -> r1
    MOV.W       D_PCCR,   r0         ! D_PCCR -> r0
    MOV.W       r0,       @r1
    MOV.L       PDCRH1,   r1         ! PDCRH1   -> r1
    MOV.W       D_PDCRH1, r0         ! D_PDCRH1 -> r0
    MOV.W       r0,       @r1
    MOV.L       PDCRH2,   r1         ! PDCRH2   -> r1
    MOV.W       D_PDCRH2, r0         ! D_PDCRH2 -> r0
    MOV.W       r0,       @r1
    MOV.L       PDCRL,    r1         ! PDCRL   -> r1
    MOV.W       D_PDCRL,  r0         ! D_PDCRL -> r0
    MOV.W       r0,       @r1
    NOP

!-----------------------------------------------------------------------------
! ROMに格納されているデータ(変数など)をRAM領域にコピーする
!   RAM_BGN  : データを格納するRAM領域の開始アドレス
!   RAM_END : データを格納するRAM領域の終了アドレス
!   ROM_BGN : 実際にデータが書き込まれているROM領域の開始アドレス
!-----------------------------------------------------------------------------
    MOV.L       RAM_BGN,  r0        ! RAM_BGN -> r0
    MOV.L       RAM_END,  r1        ! RAM_END -> r1
    MOV.L       ROM_BGN,  r2        ! ROM_BGN -> r2
    BRA         LOOP11
    NOP
LOOP1:
    MOV.B       @r2,    r3          ! ROM領域からデータを取得
    MOV.B       r3,     @r0         ! RAM領域へデータをコピー
    ADD         #1,     r0          ! RAM領域を指すアドレスをインクリメント
    ADD         #1,     r2          ! ROM領域を指すアドレスをインクリメント
LOOP11:
    CMP/eq      r0,     r1          ! RAM_BGN == RAM_END ならば T=1
    BF          LOOP1               ! T!=1 ならば LOOP1へ
    NOP
END_LOOP1:

!-----------------------------------------------------------------------------!
!   初期化無しのグローバル変数を0で初期化
!   BSS_BGN  : 初期化無しのグローバル変数が格納されている開始アドレス
!   BSS_END : 初期化無しのグローバル変数が格納されている終了アドレス
!-----------------------------------------------------------------------------
    MOV.L       BSS_BGN,  r0        ! BSS_BGN -> r0
    MOV.L       BSS_END,  r1        ! BSS_END -> r1
    BRA         LOOP21
    NOP
LOOP2:
    MOV         #0,     r3          ! r3=0
    MOV.B       r3,     @r0         ! グローバル変数の領域に0を代入
    ADD         #1,     r0          ! 領域を指すアドレスをインクリメント
LOOP21:
    CMP/eq      r0,     r1          ! BSS_BGN == BSS_END ならば T=1
    BF          LOOP2               ! T!=1 ならば LOOP2へ
    NOP
END_LOOP2:

!-----------------------------------------------------------------------------
! main関数呼び出し
!-----------------------------------------------------------------------------
START_MAIN:                         ! mainをCALL
    MOV.L       MAIN_ADRS, r0       ! main関数のアドレス -> R0
    JSR         @r0                 ! mainへのジャンプサブルーチン
    OR          r0,     r0          ! JSR命令は遅延分岐のため
                                    ! (遅延分岐とはJSR直後の命令を先に実行)

! 万が一mainが終了して戻ってきても無限ループにして停止させる
FOREVER:
    BRA         FOREVER
    OR          r0,     r0

.align  4                               ! 4Byte = 32Bit固定
!----実行時に参照される初期値有りデータの領域(RAM領域)----
RAM_BGN:            .long   _dataRAM_begin    ! 開始アドレス
RAM_END:            .long   _dataRAM_end      ! 終了アドレス
!----リンク時に参照される初期値有りデータの初期値領域(ROM領域)----
ROM_BGN:            .long   _dataROM_begin    ! 開始アドレス
!----実行時に参照される初期値なしデータの領域(RAM領域)----
BSS_BGN:            .long   _bss_begin        ! 開始アドレス
BSS_END:            .long   _bss_end          ! 終了アドレス

STACK_ROOT:         .long   0x0               !スタックポインタの初期値
MAIN_ADRS:          .long   _main             !main関数

    .align  4
BCR1:    .long 0xffff8620
BCR2:    .long 0xffff8622
WCR1:    .long 0xffff8624
PACRH:   .long 0xffff8388
PACRL1:  .long 0xffff838c
PBCR1:   .long 0xffff8398
PBCR2:   .long 0xffff839a
PCCR:    .long 0xffff839c
PDCRH1:  .long 0xffff83a8
PDCRH2:  .long 0xffff83aa
PDCRL:   .long 0xffff83ac

D_BCR1:    .short 0x202f ! CS0/CS2/CS3 are 16bit-bus,CS is 32 bit
D_BCR2:    .short 0x5510 ! wait 1 idle
D_WCR1:    .short 0x0002 ! CS0 is 2 wait, CS1-3 are 0 wait
D_PACRH:   .short 0x5020 ! WRHH WRHL DRAK0 are enable
D_PACRL1:  .short 0x5550 ! CK -RD -WRH -WRL -CS[1..0] are enable
D_PBCR1:   .short 0x000a ! A21/A20 are enable
D_PBCR2:   .short 0xa005 ! A19/A18/A17/16 are enable
D_PCCR:    .short 0xffff ! A15-0 are enable
D_PDCRH1:  .short 0x5555 ! D31-24 are enable
D_PDCRH2:  .short 0x5555 ! D23-16 are enable
D_PDCRL:   .short 0xffff ! D15-0 are enable

! void setIntMask(int mask)   r4:mask r2:work r1:srreg
    .align  4
    .global _setIntMask
_setIntMask:
    stc      sr,r1          ! srreg = __sr__
    mov.l    MASKVALUER,r2
    and      r2,r1          ! srreg &= 0xffffff0f
    shll2    r4             ! mask <<= 2
    shll2    r4             ! mask <<= 2
    mov.l    MASKVALUE,r2
    and      r2,r4          ! mask &= 0x00f0
    or       r4,r1          ! srreg |= mask
    ldc      r1,sr
    rts 
    nop

! この関数はIntMaskを返します。
! int getIntMask(void)
    .align  4
    .global _getIntMask
_getIntMask:
    stc      sr,r0
    mov.l    MASKVALUE,r2
    and      r2,r0
    shlr2    r0
    shlr2    r0
    rts 
    nop

    .align  4
MASKVALUE:    .long  0x000000f0
MASKVALUER:   .long  0xffffff0f

! 次の関数はリンカがデフォルト関数群をつけるのを防ぎます
    .align  4
    .global ___main
___main:
    rts 
    nop

.end


































[A]




[B]









































[C]






































[D]





















































[E]













[F]

 

【5】リンクオプションを記述したリンカスクリプトファイル(romsh7045.x)


標準AKI-SH2/7045向けのリンカスクリプトファイル(.xファイル)には次のようにセクションのメモリ配置を記述する。

/*****************************************************************************
         リンカスクリプト 1Dec2003 coskx A.Yamashita

機械語のプログラムやデータの配置(どこのアドレスに配置するか)を決めます

キーワード
OUTPUT_ARCH マシンのアーキテクチャ
ENTRY       プログラムの中で実行する最初の命令の位置を設定
MEMORY      メモリブロックの位置とサイズを記述
SECTIONS    出力ファイルのメモリレイアウトを記述

セクションの名前
.vector  割り込みベクタテーブル
.text    プログラム機械語コード,定数(静的文字列を含む)
.data    外部変数,static変数で初期化(宣言時に値が代入されている)済の変数
.bss     外部変数,static変数で初期化なしの変数

int aaa=1234;                   aaaは.dataに確保される
int bbb;                        bbbは.bssに確保される
const int bbb1=5678;            bbb1は.textに確保される

main()
{
    int ccc;                    cccはスタックに動的に確保される
      :
}

int func(void)
{
    static int ddd=0;           dddは.dataに確保される
    static int eee;             eeeは.bssに確保される
    int fff;                    fffはスタックに動的に確保される
      :
    fff += 2345;                2345は.textに確保される
      :
}
******************************************************************************/
OUTPUT_ARCH(sh)
ENTRY("_start")
MEMORY
{
    /* 内臓ROM 0x00000000〜0x0003ffff */
    /* 内臓I/O 0xffff8000〜0xffff87ff */
    /* 内臓RAM 0xfffff000〜0xffffffff */
    /* 外部RAM 0x00400000〜0x0041ffff */
    vect(r)         : org = 0x00000000, len = 0x280
    rom(rx)         : org = 0x00000280, len = 256k-0x280
    ram2(rwx)       : org = 0x00400000, len = 1024k
    ram(rwx)        : org = 0xfffff000, len = 4k
}
SECTIONS
{
    .vector : {
        /* 0 */
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(0))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(0))
        /* 4 */
        LONG(DEFINED(_int_GeneralIllegalInstruction)?ABSOLUTE(_int_GeneralIllegalInstruction):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(DEFINED(_int_SlotIllegalInstruction)?ABSOLUTE(_int_SlotIllegalInstruction):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 8 */
        LONG(ABSOLUTE(_start))
        LONG(DEFINED(_int_CPUAddressError)?ABSOLUTE(_int_CPUAddressError):ABSOLUTE(_start))
        LONG(DEFINED(_int_DMAAddressError)?ABSOLUTE(_int_DMAAddressError):ABSOLUTE(_start))
        LONG(DEFINED(_int_NMI)?ABSOLUTE(_int_NMI):ABSOLUTE(_start))
        /* 12 */
        LONG(DEFINED(_int_Userbrake)?ABSOLUTE(_int_Userbrake):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 16 */
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 20 */
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 24 */
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 28 */
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 32 */
        LONG(DEFINED(_int_trap0)?ABSOLUTE(_int_trap0):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap1)?ABSOLUTE(_int_trap1):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap2)?ABSOLUTE(_int_trap2):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap3)?ABSOLUTE(_int_trap3):ABSOLUTE(_start))
        /* 36 */
        LONG(DEFINED(_int_trap4)?ABSOLUTE(_int_trap4):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap5)?ABSOLUTE(_int_trap5):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap6)?ABSOLUTE(_int_trap6):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap7)?ABSOLUTE(_int_trap7):ABSOLUTE(_start))
        /* 40 */
        LONG(DEFINED(_int_trap8)?ABSOLUTE(_int_trap8):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap9)?ABSOLUTE(_int_trap9):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap10)?ABSOLUTE(_int_trap10):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap11)?ABSOLUTE(_int_trap11):ABSOLUTE(_start))
        /* 44 */
        LONG(DEFINED(_int_trap12)?ABSOLUTE(_int_trap12):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap13)?ABSOLUTE(_int_trap13):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap14)?ABSOLUTE(_int_trap14):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap15)?ABSOLUTE(_int_trap15):ABSOLUTE(_start))
        /* 48 */
        LONG(DEFINED(_int_trap16)?ABSOLUTE(_int_trap16):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap17)?ABSOLUTE(_int_trap17):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap18)?ABSOLUTE(_int_trap18):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap19)?ABSOLUTE(_int_trap19):ABSOLUTE(_start))
        /* 52 */
        LONG(DEFINED(_int_trap20)?ABSOLUTE(_int_trap20):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap21)?ABSOLUTE(_int_trap21):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap22)?ABSOLUTE(_int_trap22):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap23)?ABSOLUTE(_int_trap23):ABSOLUTE(_start))
        /* 56 */
        LONG(DEFINED(_int_trap24)?ABSOLUTE(_int_trap24):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap25)?ABSOLUTE(_int_trap25):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap26)?ABSOLUTE(_int_trap26):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap27)?ABSOLUTE(_int_trap27):ABSOLUTE(_start))
        /* 60 */
        LONG(DEFINED(_int_trap28)?ABSOLUTE(_int_trap28):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap29)?ABSOLUTE(_int_trap29):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap30)?ABSOLUTE(_int_trap30):ABSOLUTE(_start))
        LONG(DEFINED(_int_trap31)?ABSOLUTE(_int_trap31):ABSOLUTE(_start))
        /* 64 */
        LONG(DEFINED(_int_irq0)?ABSOLUTE(_int_irq0):ABSOLUTE(_start))
        LONG(DEFINED(_int_irq1)?ABSOLUTE(_int_irq1):ABSOLUTE(_start))
        LONG(DEFINED(_int_irq2)?ABSOLUTE(_int_irq2):ABSOLUTE(_start))
        LONG(DEFINED(_int_irq3)?ABSOLUTE(_int_irq3):ABSOLUTE(_start))
        /* 68 */
        LONG(DEFINED(_int_irq4)?ABSOLUTE(_int_irq4):ABSOLUTE(_start))
        LONG(DEFINED(_int_irq5)?ABSOLUTE(_int_irq5):ABSOLUTE(_start))
        LONG(DEFINED(_int_irq6)?ABSOLUTE(_int_irq6):ABSOLUTE(_start))
        LONG(DEFINED(_int_irq7)?ABSOLUTE(_int_irq7):ABSOLUTE(_start))
        /* 72 */
        LONG(DEFINED(_int_dei0)?ABSOLUTE(_int_dei0):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 76 */
        LONG(DEFINED(_int_dei1)?ABSOLUTE(_int_dei1):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 80 */
        LONG(DEFINED(_int_dei2)?ABSOLUTE(_int_dei2):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 84 */
        LONG(DEFINED(_int_dei3)?ABSOLUTE(_int_dei3):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 88 */
        LONG(DEFINED(_int_tgi0a)?ABSOLUTE(_int_tgi0a):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi0b)?ABSOLUTE(_int_tgi0b):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi0c)?ABSOLUTE(_int_tgi0c):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi0d)?ABSOLUTE(_int_tgi0d):ABSOLUTE(_start))
        /* 92 */
        LONG(DEFINED(_int_tci0v)?ABSOLUTE(_int_tci0v):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 96 */
        LONG(DEFINED(_int_tgi1a)?ABSOLUTE(_int_tgi1a):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi1b)?ABSOLUTE(_int_tgi1b):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 100 */
        LONG(DEFINED(_int_tci1v)?ABSOLUTE(_int_tci1v):ABSOLUTE(_start))
        LONG(DEFINED(_int_tci1u)?ABSOLUTE(_int_tci1u):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 104 */
        LONG(DEFINED(_int_tgi2a)?ABSOLUTE(_int_tgi2a):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi2b)?ABSOLUTE(_int_tgi2b):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 108 */
        LONG(DEFINED(_int_tci2v)?ABSOLUTE(_int_tci2v):ABSOLUTE(_start))
        LONG(DEFINED(_int_tci2u)?ABSOLUTE(_int_tci2u):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 112 */
        LONG(DEFINED(_int_tgi3a)?ABSOLUTE(_int_tgi3a):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi3b)?ABSOLUTE(_int_tgi3b):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi3c)?ABSOLUTE(_int_tgi3c):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi3d)?ABSOLUTE(_int_tgi3d):ABSOLUTE(_start))
        /* 116 */
        LONG(DEFINED(_int_tci3v)?ABSOLUTE(_int_tci3v):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 120 */
        LONG(DEFINED(_int_tgi4a)?ABSOLUTE(_int_tgi4a):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi4b)?ABSOLUTE(_int_tgi4b):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi4c)?ABSOLUTE(_int_tgi4c):ABSOLUTE(_start))
        LONG(DEFINED(_int_tgi4d)?ABSOLUTE(_int_tgi4d):ABSOLUTE(_start))
        /* 124 */
        LONG(DEFINED(_int_tci4v)?ABSOLUTE(_int_tci4v):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 128 */
        LONG(DEFINED(_int_eri0)?ABSOLUTE(_int_eri0):ABSOLUTE(_start))
        LONG(DEFINED(_int_rxi0)?ABSOLUTE(_int_rxi0):ABSOLUTE(_start))
        LONG(DEFINED(_int_txi0)?ABSOLUTE(_int_txi0):ABSOLUTE(_start))
        LONG(DEFINED(_int_tei0)?ABSOLUTE(_int_tei0):ABSOLUTE(_start))
        /* 132 */
        LONG(DEFINED(_int_eri1)?ABSOLUTE(_int_eri1):ABSOLUTE(_start))
        LONG(DEFINED(_int_rxi1)?ABSOLUTE(_int_rxi1):ABSOLUTE(_start))
        LONG(DEFINED(_int_txi1)?ABSOLUTE(_int_txi1):ABSOLUTE(_start))
        LONG(DEFINED(_int_tei1)?ABSOLUTE(_int_tei1):ABSOLUTE(_start))
        /* 136 */
        LONG(DEFINED(_int_adi0)?ABSOLUTE(_int_adi0):ABSOLUTE(_start))
        LONG(DEFINED(_int_adi1)?ABSOLUTE(_int_adi1):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 140 */
        LONG(DEFINED(_int_swdtce)?ABSOLUTE(_int_swdtce):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 144 */
        LONG(DEFINED(_int_cmi0)?ABSOLUTE(_int_cmi0):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 148 */
        LONG(DEFINED(_int_cmi1)?ABSOLUTE(_int_cmi1):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 152 */
        LONG(DEFINED(_int_iti)?ABSOLUTE(_int_iti):ABSOLUTE(_start))
        LONG(DEFINED(_int_cmi)?ABSOLUTE(_int_cmi):ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        LONG(ABSOLUTE(_start))
        /* 156 */
        LONG(DEFINED(_int_oei)?ABSOLUTE(_int_oei):ABSOLUTE(_start))
        FILL(0xff)
    } > vect                         /*ここまでをvect領域に割り付ける*/
    .text : {
        CREATE_OBJECT_SYMBOLS
        *(.text)                     /*すべてのソースファイルの.textセクションをここに*/
        _dataROM_begin = .;          /*変数_dataROM_beginにカレントのアドレスを代入*/
    }  > rom                         /*ここまでをrom領域に割り付ける*/
    .data : AT (_dataROM_begin) {    /*AT 初期値データを_dataROM_beginに書き込む*/
        _dataRAM_begin = .;          /*変数_dataRAM_beginにカレントのアドレスを代入*/
        *(.data)                     /*すべてのソースファイルの.dataセクションをここに*/
        _dataRAM_end = .;            /*変数_dataRAM_endにカレントのアドレスを代入*/
    } > ram2                         /*ここまでをram2領域に割り付ける*/
    .bss : {
        _bss_begin = .;              /*変数_bss_beginにカレントのアドレスを代入*/
        *(.bss)                      /*すべてのソースファイルの.bssセクションをここに*/
        _bss_end = .;                /*変数_bss_endにカレントのアドレスを代入*/
    }  >ram2                         /*ここまでをram2領域に割り付ける*/
}

/*******************************************************************************
補足説明

リンク作業により次の各変数(5個)の値が定まります。これらの変数はスタートアップル
ーチンで利用されます。
_dataROM_begin    .dataセクションのメモリイメージで初期値が並ぶ先頭アドレス
                  この領域がユーザプログラム実行時に参照されることはない
_dataRAM_begin    .dataセクションの先頭アドレス
_dataRAM_end      .dataセクションの末尾アドレス+1
_bss_begin        .bssセクションの先頭アドレス
_bss_end          .bssセクションの末尾アドレス+1

初期化されたグローバル変数(先の例ではint aaaa=1234;)がRAM上に配置されると,電
源が切れた状態では初期値1234を覚えておくことが出来ない。またROM上に配置されると,
ユーザプログラムで値を変更することが出来ない。
そこでこのような変数は,実行プログラムではRAM領域にその変数があるように機械語コ
ードを作っておき,初期値はROM領域に書きこむようになる。同じ変数のめもり割り当て
を二重化するために「AT」コマンドが使われる。
ROM領域に書き込まれた初期値をユーザプログラムが動き出す前にRAM領域にコピーするこ
とはスタートアップルーチンの仕事の1つです。
*******************************************************************************/

各セクションの意味は次の通り

.text............................プログラム領域(Cで記述したプログラムのオブジェクトもここに入る)
.text............................コンスタント領域(Cで記述したプログラムの,constのついたグローバル変数とconstのついたstatic変数はここに入る)
.data............................データ領域(Cで記述したプログラムの,初期化されたグローバル変数のRAM割り当て領域)

           [初期値は「AT」で指定されたアドレスすなわち.textの後ろに連続して配置される]
.bss............................データ領域(Cで記述したプログラムの,初期化されていないグローバル変数のRAM割り当て領域)