0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

32ビットARMアセンブリでBL/BX LRの動作を確認

Last updated at Posted at 2025-10-07

目的

筆者は最近任天堂GBAのプログラムを研究しています。

昨日投稿した記事
アセンブリでGBAプログラミング:ボタン判定
の中でGBA向けに以下のようなコードを書きました。

    @ 押されたら塗り潰し
    bl FillScreenRed

@ ...省略...

FillScreenRed:
    push {lr}

    @ VRAM = 0x06000000
    ldr r0, =0x06000000
    mov r1, #0x1F        @ 赤 (RGB15)
    ldr r2, =38400       @ 240*160

FillLoop:
    strh r1, [r0], #2
    subs r2, r2, #1
    bne FillLoop

    pop {lr}
    bx lr

BL命令を実行すると、戻り先のアドレスが自動的にLR レジスタに格納されます。そのため、bl ラベルで関数に跳び、bx lrで呼び出し元の次の命令に戻ることができます。

この書き方はARMでの定石ですが、本当にLR レジスタに戻り先のアドレスが入っているのかを確認してみます。
GBAではデバッグが難しいため、今回はLinuxが動作するARM環境で実験します。

追記: 64ビットでも同様の検証を行いました。
64ビットARMアセンブリでBL RETの動作を確認

検証用コード

test.s
    .global _start

_start:
    mov r0, #42       @ 引数に42を入れる
    bl myfunc          @ 関数呼び出し
    b .                @ 無限ループ

myfunc:
    add r0, r0, #1     @ 引数を+1
    bx lr              @ 呼び出し元に戻る

コンパイル後、逆アセンブルすると命令毎の実際のアドレスが確認できます。

as -o test.o test.s
ld -o test test.o
objdump -d test > test.asm
test.asm
test:     file format elf32-littlearm


Disassembly of section .text:

00010054 <_start>:
   10054:       e3a0002a        mov     r0, #42 @ 0x2a
   10058:       eb000000        bl      10060 <myfunc>
   1005c:       eafffffe        b       1005c <_start+0x8>

00010060 <myfunc>:
   10060:       e2800001        add     r0, r0, #1
   10064:       e12fff1e        bx      lr

GDBを使い、myfuncに入ったところにブレイクポイントを置き、LRレジスタの中に本当に返りアドレスが格納されているかを確認します。

gdb ./test
break *0x10060
run
display/x $lr
quit

実際の操作記録

$lr = 0x1005cと表示されており、実際にLR レジスタb .のアドレスが格納されていることが確認できます。

testuser@CasaOS:~/atest$ cat test.s
    .global _start

_start:
    mov r0, #42       @ 引数に42を入れる
    bl myfunc          @ 関数呼び出し
    b .                @ 無限ループ

myfunc:
    add r0, r0, #1     @ 引数を+1
    bx lr              @ 呼び出し元に戻る

testuser@CasaOS:~/atest$ as -o test.o test.s
testuser@CasaOS:~/atest$ ld -o test test.o
testuser@CasaOS:~/atest$ objdump -d test > test.asm
testuser@CasaOS:~/atest$ cat test.asm

test:     file format elf32-littlearm


Disassembly of section .text:

00010054 <_start>:
   10054:       e3a0002a        mov     r0, #42 @ 0x2a
   10058:       eb000000        bl      10060 <myfunc>
   1005c:       eafffffe        b       1005c <_start+0x8>

00010060 <myfunc>:
   10060:       e2800001        add     r0, r0, #1
   10064:       e12fff1e        bx      lr
testuser@CasaOS:~/atest$ gdb ./test
GNU gdb (Debian 13.1-3) 13.1
Copyright (C) 2023 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "arm-linux-gnueabihf".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./test...
(No debugging symbols found in ./test)
(gdb) break *0x10060
Breakpoint 1 at 0x10060
(gdb) run
Starting program: /home/testuser/atest/test

Breakpoint 1, 0x00010060 in myfunc ()
(gdb) display/x $lr
1: /x $lr = 0x1005c
(gdb) quit
A debugging session is active.

        Inferior 1 [process 3260] will be killed.

Quit anyway? (y or n) y
testuser@CasaOS:~/atest$

image.png
image.png

動作環境(Linux / ARM 版)

  • OS: Armbian 23.08.0-trunk (Debian 12 Bookworm)
  • Kernel: Linux 6.1.38-meson (armv7l)
  • CPU: ARM Cortex-A5, 4 cores, Little Endian
  • GCC: 12.2.0
  • Architecture: armv7l
  • 備考: Windows10からSSH接続して使用

動作環境確認コマンドは以下の通り

uname -a
cat /etc/os-release
gcc --version
lscpu
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?