我一直編程臂/拇指多年的許多彙編程序,並需要很少的許多指令。
.thumb_func非常重要,正如其他響應者指出的那樣。
例如
.globl _start
_start:
b reset
reset:
.arm
.globl one
one:
add r0,r0,#1
bx lr
.thumb
.globl two
two:
add r0,r0,#2
bx lr
.thumb_func
.globl three
three:
add r0,r0,#3
bx lr
.word two
.word three
.ARM或曾經是像.code32或.CODE 32告訴它這是ARM代碼不Thumb代碼,這對於你的Cortex-M3的你不會需要使用。
.thumb同樣,曾經是.code 16或者也許仍然有效,同樣的處理使得下面的代碼不是手臂。
如果您正在使用的標籤是不是你需要從其他文件轉移到或間接,那麼不會需要.thumb_func全球標籤。但是爲了正確地計算分支到這些全局標籤之一的地址(lsbit是拇指1和手臂0),您要將其標記爲拇指或手臂標籤,而thumb_func則可以這樣做,否則您有支化增加更多的代碼之前,以設置位和標籤不是可調用從C.
00000000 <_start>:
0: eaffffff b 4 <one>
00000004 <one>:
4: e2800001 add r0, r0, #1
8: e12fff1e bx lr
0000000c <two>:
c: 3002 adds r0, #2
e: 4770 bx lr
00000010 <three>:
10: 3003 adds r0, #3
12: 4770 bx lr
14: 0000000c andeq r0, r0, ip
18: 00000011 andeq r0, r0, r1, lsl r0
截至.thumb彙編是如所期望臂代碼。
這兩個和三個標籤/函數都是所需的拇指代碼,但是兩個標籤有一個偶數地址,而三個標籤具有適當的奇數地址。
最新的codesourcery工具被用來彙編,鏈接和轉儲上面的示例。
現在對於一切都是拇指(/ thumb2)的cortex-m3來說,thumb_func可能不是那麼重要,它可能只與命令行開關一起工作(很容易做一個實驗來找出)。儘管如此,如果您將拇指專用處理器轉移到普通的手臂/拇指核心,這是一個好習慣。
彙編通常喜歡添加所有這些指令和其他方式使外觀看起來更像一種高級語言。我只是說你不必使用它們,我將組裝器用於手臂,併爲許多不同的處理器使用許多不同的裝配器,並且更少選擇更多方法,這意味着關注裝配本身並儘可能少使用特定工具。通常情況下,我通常不是規則的例外,所以你可以通過查看編譯器輸出生成的指令(並通過文檔驗證)來找出更常用的指令。
unsigned int one (unsigned int x)
{
return(x+1);
}
.arch armv5te
.fpu softvfp
.eabi_attribute 20, 1
.eabi_attribute 21, 1
.eabi_attribute 23, 3
.eabi_attribute 24, 1
.eabi_attribute 25, 1
.eabi_attribute 26, 2
.eabi_attribute 30, 2
.eabi_attribute 18, 4
.file "bob.c"
.text
.align 2
.global one
.type one, %function
one:
.fnstart
.LFB0:
@ args = 0, pretend = 0, frame = 0
@ frame_needed = 0, uses_anonymous_args = 0
@ link register save eliminated.
add r0, r0, #1
bx lr
.fnend
.size one, .-one
.ident "GCC: (Sourcery G++ Lite 2010.09-50) 4.5.1"
.section .note.GNU-stack,"",%progbits
我與彙編混合ARM和Thumb彙編程序或數據時使用.align僞,你會期望彙編這樣的平臺就知道是在半字邊界和ARM指令爲Thumb指令爲明顯的東西與單詞邊界對齊。這些工具並不總是那麼聰明。灑上.aligns大約不會受傷
.text是默認,所以這是有點多餘的,但不會傷害。 .text和.data是標準屬性(不是arm所特有的),如果你正在編譯目標上的ROM和RAM組合,你可能會關心(取決於你對鏈接描述文件所做的),否則.text將適用於所有的。
.size顯然該函數的大小從該指令開始。彙編程序不能自己弄清楚,所以如果這個函數的大小對於你的代碼,鏈接器腳本,調試器,加載程序很重要,那麼這需要正確,否則你不必費心。一個函數是一個高層次的概念,無論如何,彙編器並不具備聲明其大小的功能。而C編譯器肯定不在意,它只是尋找一個分支到的標籤,而在arm系列的情況下,它是分支到的拇指代碼或者手臂代碼。
如果你在很長時間的代碼中懶惰地使用你的立即數(ldr rx,= 0x12345678),你可能會發現.pool指令(有一個更新的等價物)。再次,這些工具並不總是足夠聰明,可以在無條件分支之後放置這些數據,但有時您會告訴它們。我認爲懶惰的一半是嚴肅認真的,始終做標籤:.word是件痛苦的事情,我相信arm和gcc工具都可以用於這個快捷方式,所以我和其他人一樣使用它。
另請注意llvm會輸出一個額外的.eabi_attribute或兩個由代碼sourcery的版本/ mods支持的binutils,但不受gnu發佈的binutils支持(可能還有)。兩個解決方案可以工作,修改llvm的asm打印函數,不寫入eabi_attributes或至少用註釋(@)編寫它們,或者從源代碼獲取binutils源代碼/ mods,並以這種方式構建binutils。代碼源往往會導致gnu(例如thumb2支持)或者反向運行新功能,所以我認爲這些llvm attrubutes不久將會出現在主線binutils中。通過修剪llvm編譯代碼中的eabi_attributes,我沒有受到任何不良影響。
這裏是上述相同功能的llvm輸出,顯然這是我修改後的註釋掉eabi_attributes的llc。
.syntax unified
@ .eabi_attribute 20, 1
@ .eabi_attribute 21, 1
@ .eabi_attribute 23, 3
@ .eabi_attribute 24, 1
@ .eabi_attribute 25, 1
@ .eabi_attribute 44, 1
.file "bob.bc"
.text
.globl one
.align 2
.type one,%function
one: @ @one
@ BB#0: @ %entry
add r0, r0, #1
bx lr
.Ltmp0:
.size one, .Ltmp0-one
ELF文件格式是有據可查的,很容易解析,如果你想真正看到什麼精靈特定指令(如果有的話)都在做。許多這些指令都是爲了幫助鏈接器。例如.thumb_func,.text,.data。
我已經添加了一個賞金問題,希望得到更詳盡的答案,特別是關於.type和.size指令。 – Oystein 2010-12-14 22:26:11
這應該被拆分成每個指令的問題。建議:理解ELF格式,然後在使用和不使用每個指令的情況下創建最小示例,編譯並在其上使用'readelf -a'。 – 2015-07-15 12:29:13