2013-05-20 95 views
0

我想加載一個32位常量到一個寄存器中,我發現一個僞指令「mov32」可以在其上執行此操作(mov32 pseudo-instruction)。然後,我編寫一個彙編文件,其中包括:ARM程序集:錯誤的指令「mov32」

MOV32 r0, #0xABCDEF12 

並與Linaro的工具鏈編譯它(13.04版):

arm-linux-gnueabihf-as -march=armv7-a -mcpu=cortex-a9 test.s -o test.o 

但與消息失敗:

Error: bad instruction `mov32 r0, #0xABCDEF12' 

我不不知道這是否是統一彙編語言的問題。在這種情況下,我在源代碼中編寫了「.syntax unified」並再次測試,但也失敗了。 GNU工具鏈是否支持ARM僞指令,如「mov32」,「ldr r0,= address」等?如果確實如此,我該如何解決這個問題?謝謝。

+1

LDR RX = 0x12345678的會爲你工作與GNU工具。 –

+0

您正在使用gnu彙編程序和arm彙編僞指令。 – auselen

回答

2

正如一位評論者所提到的,MOV32是一個由ARM自己的開發工具支持的pdu指令。由於您使用的是GNU工具鏈,因此您有幾種選擇:

您可以按照提及的方式使用LDR R0,=0xABCDEF12
這也是一個僞指令,這將導致立即被置於文字池(分散在整個代碼部分的小數據塊)中,然後使用與PC相關的LDR進行加載。
如果常量可以編碼爲imm8 ROR n(它不能用於你的情況,但假設你有0x80000000),那麼psedo指令將被翻譯成一個單一的MOV,並且不會向文字池添加任何東西。


您也可以使用指令MOV32翻譯成:

MOVW R0,#0xEF12 
MOVT R0,#0xABCD 

這需要ARMv6T2或更高版本。

2

在GNU彙編程序,可以合成mov32方式如下:

.macro mov32, reg, val 
    movw \reg, #:lower16:\val 
    movt \reg, #:upper16:\val 
.endm

這會爲ARMv7的工作。如果您想要「通用」行爲(將其替換爲ldr reg,=val,其中movw/movt不存在),請添加一份#ifdef

(信貸,信貸是因爲:這是來自的ARM Linux內核源,我的不是發明arch/arm/mach-tegra/sleep.h

+0

Protip:鏈接到git散列而不是分支。 – MBober