ARM アセンブラ BLX/BX で Thumb コード混在
末尾が X のブランチ命令
BLX (Branch with Link and eXchange)
BX (Branch and eXchange)
では ARM <--> Thumb モードの切替ができます。BX (Branch and eXchange)
BLX/BX ともにレジスタあるいはラベルをオペランドに指定できますが、ARM Compiler toolchain Assembler Reference によると、
BLX label always changes the state.とのことなので、ラベルを使うと常にモードが切り替わるようです。
下記のコードで試してみました。
mrs.s
mrs.s
.text .global _start _start: mrs r0, apsr blx mrs_t mov r0, #0 mov r7, #1 svc #0
mrs_t.s
.text .global mrs_t mrs_t: mrs r0, apsr bx lr
ビルドは以下のコマンドで、mrs_t.s を Thumb でコンパイルしています。
arm-xilinx-linux-gnueabi-as -g -o mrs.o mrs.s arm-xilinx-linux-gnueabi-as -mthumb -g -o mrs_t.o mrs_t.s arm-xilinx-linux-gnueabi-ld mrs.o mrs_t.o
gdb でステップ実行しながら CPSR の値を確認しました。
(gdb) target remote localhost:1234 Remote debugging using localhost:1234 _start () at mrs.s:4 4 mrs r0, apsr (gdb) print /x $cpsr $1 = 0x10 (gdb) s 6 blx mrs_t (gdb) print /x $cpsr $2 = 0x10 (gdb) s mrs_t () at mrs_t.s:4 4 mrs r0, apsr (gdb) print /x $cpsr $3 = 0x30 (gdb) s 5 bx lr (gdb) print /x $cpsr $4 = 0x30 (gdb) s _start () at mrs.s:8 8 mov r0, #0 (gdb) print /x $cpsr $5 = 0x10 (gdb) c Continuing. [Inferior 1 (process 952) exited normally] (gdb) quit