5

サブルーチンを使用するために、このARM アセンブリ プログラム (ページの下部を参照) を変更しようとしました。GBA では赤い画面が表示されるはずですが (サンプル プログラムをコンパイルすると実際に表示されるため、ツールチェーンの使用上の問題ではありません)、実行すると画面が代わりに黒くなります。私はdevkitARM 30を使用しています

.arm
.text
.global main
main:
    mov r0, #0x4000000
    mov r1, #0x400
    add r1, r1, #3
    str r1, [r0]
    mov r0, #0x6000000
    stmdb sp!, {r0, r2, lr} @push registers before calling
    mov r0, #0xff
    mov r1, #0
    mov r2, #0
    bl set_rgb
    mov r1, r0
    ldmdb sp!, {r0, r2, lr} @restore registers
    mov r2, #0x9600
loop1:
    strh r1, [r0], #2
    subs r2, r2, #1
    bne loop1
infin:
    b infin

set_rgb:
    @r0: R; r1: G; r2: B; r0: RGB

    @truncate everything but the least significant five bits
    and r0, r0, #0x1f
    and r1, r1, #0x1f
    and r2, r2, #0x1f
    @form the color
    orr r0, r0, r1, lsl #5
    orr r0, r0, r2, lsl #10
    mov pc, lr @return

問題は、このプログラムの何が問題なのかということです。

4

2 に答える 2

4

私は自分でそれを解決しました。

問題は、スタックの使用方法でした。andの代わりにstmdbandldmdbを使用する必要がstmfdありldmfdました。

于 2010-04-26T13:38:40.940 に答える
1

stmdb前にデクリメントし、そのアドレスを使用してスタックへの書き込みを開始することを意味します。これは適切です。

ldmia後のインクリメントを意味するので、現在のスタックポインタから始めて値をレジスタに読み戻してから、スタックポインタをインクリメントします。

fd命名法は私には意味がありませんでした。jump if equal と jump if zero はすべてのプロセッサで同じ命令でldmありstm、一部の asms は両方を提供します。dbiafd

ldmia( ) の後にインクリメントし、( ) の前にデクリメントする方が覚えやすいと思いますldmdb。または、何らかの理由でロード/ストア方向を少し変えた場合でも、何をしようとしているかに応じて、前後に適切なインクリメントを選択します。

Cでは*(ptr++)vsのようなものです*(++ptr)

于 2010-04-26T14:43:10.600 に答える