2016-09-18 79 views
2

在Thumb-2代码中,不可能在大多数指令中使用寄存器8-15,但这在ARM代码中是可行的。因此,下面的组件提供了一个运行时非法指令错误:编译时寄存器检查Thumb-2代码

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

但是,我没有得到在编译时警告,即使我用-Wall

[email protected]:~/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] 
[email protected]:~/ctests$ arm-linux-gnueabihf-gcc -Wall -o high high.o 
[email protected]:~/ctests$ ./high 
Illegal instruction 
[email protected]:~/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 

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

回答

4

一个问题是,您在符号main上使用了Thumb代码,但未将其注释为Thumb符号。因此,链接器不会设置符号地址的LSB,因此在运行时,调用将在ARM状态下进入,然后在Thumb编码上进行扼流。为了解决这个问题,你需要添加.thumb_func annotation

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

有了到位,这是极有可能仍与任何未定义的指令或段错误崩溃当您运行过代码的一端插入任何代码/数据/未映射页面如下。您需要从main实际返回。

你最初的假设是不正确的,因为如果它注册使用问题,你怀疑它,它甚至不会组装。 “编译时可用于检查非法指令的工具”的汇编程序。

+0

谢谢!当我在'main'的末尾添加'bx lr'时,它会起作用。 – Keelan

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,Model B上,我试过那些标志:-march=armv8-a+crc -mtune=cortex-a53 -mfpu=crypto-neon-fp-armv8 -mfloat-abi=hard(从here)。由于它是64位ARM,因此问题不在于它不支持Thumb-2,而在于您不能在程序中切换AArch64 < - > AArch32。

+0

我明白了,谢谢。我如何找到'-march'和'-mcpu'的正确设置? [Here](http://termbin.com/r6mn)是我的'/ proc/cpuinfo';这是一个树莓派3,型号B. – Keelan

+1

@CamilStaps我认为这种情况下的问题可能是您生成的程序是一个64位的ARM程序。您的汇编程序可能会让您在这样的程序中切换到缩略模式,但生成的代码将不起作用。 – fuz

+0

@CamilStaps添加标志。我完全错过了pi @ rasppi'提示... –