ADR を使用したレジスタへのアドレスのロード

ADR 命令を使用すると、データをロードしなくても特定の範囲内のアドレスを生成することができます。ADR 命令では、PC 相対式を使用できます。PC 相対式とは、任意のオフセットに付けるラベルで、このラベルのアドレスが現在の PC の相対アドレスとります。

Note

ADR 命令で使用するラベルは、同じコードセクション内に存在している必要があります。同じコードセクション内にないラベルを参照すると、アセンブラによりエラーが返されます。

ADR 命令で使用できるアドレスの範囲は、命令セットによって異なります。

ARM

32 ビットのワード内で 8 ビットの値を右に任意の偶数ビット分ロテートして得られる任意の値。この範囲は PC からの範囲です。

32 ビット Thumb

バイト、ハーフワード、またはワード境界で整列されているアドレスから ±4095 バイトの範囲

16 ビット Thumb

0 ~ 1020 バイト。label はワード境界で整列させる必要があります。ALIGN ディレクティブを使用して、label をワード境界で整列させることができます。

Show/hideADR を使用したジャンプテーブルの実装例

Example 10 には、ジャンプテーブルを実装する ARM コードを示しています。ADR 命令では、ジャンプテーブルのアドレスをロードします。

Example 10. ARM コードによるジャンプテーブルの実装

        AREA    Jump, CODE, READONLY     ; このコードブロックに名前を付ける
        ARM                              ; 以降のコードは ARM コード
num     EQU     2                        ; ジャンプテーブルのエントリの数
        ENTRY                            ; 最初に実行する命令をマークする
start                                    ; 呼び出す最初の命令
        MOV     r0, #0                   ; 3 つのパラメータをセットアップする
        MOV     r1, #3
        MOV     r2, #2
        BL      arithfunc                ; 関数を呼び出す
stop
        MOV     r0, #0x18                ; angel_SWIreason_ReportException
        LDR     r1, =0x20026             ; ADP_Stopped_ApplicationExit
        SVC     #0x123456                ; ARM セミホスティング(以前の SWI)
arithfunc                                ; 関数にラベルを付ける
        CMP     r0, #num                 ; 関数コードを符号なし整数として処理する
        BXHS    lr                       ; コードが >= num の場合は、単純に復帰する
        ADR     r3, JumpTable            ; ジャンプテーブルのアドレスをロードする
        LDR     pc, [r3,r0,LSL#2]        ; 適切なルーチンにジャンプする
JumpTable
        DCD     DoAdd
        DCD     DoSub
DoAdd
        ADD     r0, r1, r2               ; 処理 0
        BX      lr                       ; 復帰
DoSub
        SUB     r0, r1, r2               ; 処理 1
        BX      lr                       ; 復帰
        END                              ; このファイルの終わりをマークする

Example 10では、関数 arithfunc が 3 つの引数を取り、R0 に結果を返します。最初の引数によって、2 番目と 3 番目の引数に対して実行される演算が決まります。

引数1 = 0

結果 = 引数2 + 引数3

引数1 = 1

結果 = 引数2 - 引数3

ジャンプテーブルは、以下の命令とアセンブラディレクティブを使用して実装されます。

EQU

アセンブラディレクティブです。このディレクティブを使用してシンボルに値を指定します。Example 10では、num に値 2 を割り当てます。コード内で num を使用すると、値 2 に置き換えられます。EQU のこのような使用法は、C 言語で #define を使用して定数を定義する方法と似ています。

DCD

ストアする 1 つ以上のワードを宣言します。Example 10では、各 DCD が、ジャンプテーブルの特定の節を処理するルーチンのアドレスをストアします。

LDR

LDR PC,[R3,R0,LSL#2] 命令は、ジャンプテーブルから必要な節のアドレスを PC にロードします。この命令は以下を実行します。

  • R0 が保持する節の数を 4 で乗算してワードオフセットを求める。

  • 結果をジャンプテーブルのアドレスに加算する。

  • 加算したアドレスの内容をプログラムカウンタにロードする。

Show/hide関連項目

Copyright © 2010-2011 ARM. All rights reserved.ARM DUI 0473FJ
Non-ConfidentialID111311