ARM如何告诉编译器代码所使用的指令集

创建时间:2022/1/20 20:30
更新时间:2022/1/20 21:05
作者:gi51wa2j
标签:ARM, bingo, 计算机原理, 正文

一、 汇编里指定指令集

对于IMX6ULL、STM32MP157,默认使用ARM指令集。 在汇编文件里,可以使用这样的语法告诉编译器所使用的指令集:

1.1 新语法

.arm   // 表示后续的指令使用ARM指令集 .thumb // 表示后续的指令使用thumb指令集

1.2 以前的语法

.code 32 // 表示后续的指令使用ARM指令集 .code 16 // 表示后续的指令使用thumb指令集

二、编译C文件时指定指令集

使用GCC编译时:

-marm     // 使用ARM指令集编译 -mthumb   // 使用Thumb指令集编译   //比如:   arm-linux-gcc -marm -c -o main.o main.c

2.1 举例

我们不添加该编译选项编译一个以前的文件,原先的Strat.S

然后打开生成的dis反汇编文件

查看该命令的机器码,转换为二进制为
对照资料“ARM ArchitectureReference Manual ARMv7-A and ARMv7-R edition.pdf"找到其所使用的指令,其中目标指令集是thumb指令集

2.2 修改Makefile编译选项

修改makefile的编译选项

添加-marm选项指定编译指令集

得到新的dis文件

2.3 对照举例

对照机器码,得知跳过去执行的函数是ARM指令集

2.4 结论

     无论C函数使用什么指令集,汇编指令都可以保持不变
     编译器会帮我们使用合适的机器码

三、汇编里面切换CPU状态

要切换CPU的State,比如从ARM切换到Thumb,或者从Thumb切换到ARM,可以使用BX、BLX指令:
// 如果R0的bit0为0,表示切换到ARM State; 如果R0的bit0位1,表示切换到Thumb State BX R0   BLX R0
汇编里调用C函数时,可以直接如此调用:
LDR PC, =main   // 如果main函数时用Thumb指令集编译的,最终的指令如下: // 注意到下面的c020051b,它的bit0为1 c0200010: e59ff004 ldr pc, [pc, #4] ; c020001c <AB+0x14> c0200014: c0100000 andsgt r0, r0, r0 c0200018: c02004a3 eorgt r0, r0, r3, lsr #9 c020001c: c020051b eorgt r0, r0, fp, lsl r5