编译时间寄存器检查Thumb-2代码

时间:2016-09-18 08:57:35

标签: assembly arm compiler-warnings thumb

在Thumb-2代码中,在大多数指令中不可能使用寄存器8-15,而这在ARM代码中是可行的。因此,以下程序集给出了运行时非法指令错误:

        .syntax unified
        .fpu    vfp
        .thumb
        .text
        .globl  main
main:
        str r12,[sp,#-4]    @ r12 is too high, source register is 3 bits wide

但是,即使我使用-Wall

,我也不会在编译时收到警告
pi@rasppi:~/ctests$ arm-linux-gnueabihf-as -Wall -o high.o high.s 
ARM GAS  high.s                         page 1


   1                                    .syntax unified
   2                                    .fpu    vfp
   3                                    .thumb
   4                                    .text
   5                                    .globl  main
   6                            main:
   7 0000 4DF804CC                      str r12,[sp,#-4]
pi@rasppi:~/ctests$ arm-linux-gnueabihf-gcc -Wall -o high high.o 
pi@rasppi:~/ctests$ ./high 
Illegal instruction
pi@rasppi:~/ctests$ file high
high: ELF 32-bit LSB executable, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-armhf.so.3, for GNU/Linux 2.6.32, BuildID[sha1]=c9d90a7d6386bf97a18f9da87a7b2ce422402659, not stripped

是否有任何工具可用于在编译时检查非法指令?

2 个答案:

答案 0 :(得分:4)

一个问题是您在符号main处有Thumb代码,但没有注释为Thumb符号。因此,链接器不会设置符号地址的lsb,因此在运行时调用将以ARM状态进入,然后在Thumb编码上进行阻塞。要解决此问题,您需要添加.thumb_func annotation

...
.globl main
.thumb_func
main:
...

有了这个,当您将该代码的末尾运行到任何代码/数据/未映射的页面后,很可能仍会因未定义的指令或段错误而崩溃。您需要实际从main返回。

您的初始假设是不正确的,因为如果 是您怀疑的寄存器使用问题,那么它甚至不能组装。 “可用于在编译时检查非法指令的工具”汇编程序。

答案 1 :(得分:3)

R0-R7限制仅适用于16位Thumb,而不适用于32位Thumb-2(请参阅here)。 32位STR.W有4位寄存器(编码here)。实际上,GCC确实正在生成STR.W指令(4DF804CC)。

非法指令可能是由于您的目标不支持Thumb-2引起的。您应该正确定义目标(-mthumb-march-mcpu-mfpu,...),以便汇编程序知道可以使用和不能使用的目标

现在你已经添加了你在Raspberry Pi 3,模型B上,我尝试了这些标志:-march=armv8-a+crc -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard(来自here)。由于它是64位ARM,问题不在于它不支持Thumb-2,而是你无法切换AArch64< - >你的程序中有AArch32。