2016-09-18 78 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'提示... –