LDM および STM によるブロックコピー

Example 13 には、一度に 1 ワードずつコピーすることにより、ソース位置の一連のワードをデスティネーションにコピーする ARM コードルーチンを示しています。

Example 13. LDM および STM を使用しないブロックコピー

            AREA    Word, CODE, READONLY     ; このコードブロックに名前を付ける
num         EQU     20                       ; コピーするワード数を設定する
            ENTRY                            ; 最初に呼び出す関数をマークする
start
            LDR     r0, =src                 ; r0 = ソースブロックを指すポインタ
            LDR     r1, =dst                 ; r1 = デスティネーションブロックを指すポインタ
            MOV     r2, #num                 ; r2 = コピーするワード数
wordcopy
            LDR     r3, [r0], #4             ; ソースからワードをロードし、
            STR     r3, [r1], #4             ; デスティネーションにストアする
            SUBS    r2, r2, #1               ; カウンタをデクリメントする
            BNE     wordcopy                 ; ... コピーを続ける
stop
            MOV     r0, #0x18                ; angel_SWIreason_ReportException
            LDR     r1, =0x20026             ; ADP_Stopped_ApplicationExit
            SVC     #0x123456                ; ARM セミホスティング(以前の SWI)
            AREA    BlockData, DATA, READWRITE
src         DCD     1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst         DCD     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
            END

このモジュールは、できるだけ多くのコピーできる部分に LDM 命令と STM 命令を使用することで、効率化できます。この ARM コードで指定されているレジスタの数から、一度に転送するワード数は 8 ワードが妥当です。ピーするブロックに 8 ワード単位のブロックがいくつあるかは、以下を使用して検出できます(R2 = コピーするワード数の場合)。

    MOVS   r3, r2, LSR #3    ; 8 ワード単位の数

この値を使用して、一度に 8 ワードずつコピーするループの繰り返しの回数を制御できます。残りのワード数が 8 ワードに満たない場合は、以下使用して残りのワード数を検出できます(R2 が破損していないことを前提とした場合)。

    ANDS   r2, r2, #7

Example 14 には、LDM 命令と STM 命令を使用してコピーするように書き直したブロックコピーモジュールを示しています。

Example 14. LDM および STM によるブロックコピー

            AREA    Block, CODE, READONLY    ; このコードブロックに名前を付ける
num         EQU     20                       ; コピーするワード数を設定する
            ENTRY                            ; 最初に呼び出す関数をマークする
start
            LDR     r0, =src                 ; r0 = ソースブロックを指すポインタ
            LDR     r1, =dst                 ; r1 = デスティネーションブロックを指すポインタ
            MOV     r2, #num                 ; r2 = コピーするワード数
            MOV     sp, #0x400               ; スタックポインタ(sp)をセットアップする
blockcopy
            MOVS    r3,r2, LSR #3            ; 8 ワード単位の数
            BEQ     copywords                ; 8 ワード未満を移動するかどうか
            PUSH    {r4-r11}                 ; 作業レジスタを保存する
octcopy
            LDM     r0!, {r4-r11}            ; ソースから 8 ワードをロードし、
            STM     r1!, {r4-r11}            ; デスティネーションに配置する
            SUBS    r3, r3, #1               ; カウンタをデクリメントする
            BNE     octcopy                  ; ... コピーを続ける
            POP     {r4-r11}                 ; これらは今必要ないため、
                                             ; 元の値を復元する
copywords
            ANDS    r2, r2, #7               ; コピーする残りのワード数
            BEQ     stop                     ; コピーするワードが残っていないかどうか
wordcopy
            LDR     r3, [r0], #4             ; ソースからワードをロードし、
            STR     r3, [r1], #4             ; デスティネーションにストアする
            SUBS    r2, r2, #1               ; カウンタをデクリメントする
            BNE     wordcopy                 ; ... コピーを続ける
stop
            MOV     r0, #0x18                ; angel_SWIreason_ReportException
            LDR     r1, =0x20026             ; ADP_Stopped_ApplicationExit
            SVC     #0x123456                ; ARM セミホスティング(以前の SWI)
            AREA    BlockData, DATA, READWRITE
src         DCD     1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4
dst         DCD     0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
            END

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