現在我們開發的iPhone/iPod Touch應用都是基於ARMv6、v7指令集中的ARM指令集的。ARM指令集的特點是數據處理的吞吐較大,而且可以訪問所有應用程序所能訪問的寄存器。
而在對於一些簡單操作的函數而言,有時沒必要使用ARM,Thumb指令就完全夠用。
Thumb 的特點是:空間佔用小(16位,ARM是32位;在ARMv6T2的ISA中引入了Thumb-2技術,這其中也擴增了許多32位的Thumb指令),因 此緊湊性強,從而,Cache命中率也相對ARM要高。所以在許多地方巧妙地使用Thumb指令集不僅能縮小你應用的代碼尺寸,同時也能提高你應用程序的 執行效率。
下面就來談談如何在你的項目中構建Thumb指令集。
1、必須在Device狀態下,而不能使用Simulator;
2、在你的項目偏好設置(Project->Edit Project Settings)中先找到GCC4.x - Language這一大欄,然後編輯Other C Flags,添加-mthumb-interwork,然後再添加-mno-thumb。
這時,你會看到Other C++ Flags也會增加這兩項。前一選項是ARM與Thumb交互時十分必要的,沒有這個選項你的連接就無法通過,當你存在ARM與Thumb交互時。
另外,C Flags對應於.c以及.m文件,即C和objective-C語言;C++ Flags對應於.cpp、.cxx、.cc以及.mm源文件,即C++和objective-C++語言。
3、對你所想要設置為Thumb指令集的源代碼進行配置。這裡有一點:Thumb指令集的配置只能作用於一個源文件,而無法只針對某個函數。所以這有時會帶來一些不便。
鼠標右鍵單擊你所想要變成Thumb指令的源文件,選擇Get Info,然後選擇Build選項卡,添加-mthumb即可。
我們下面可以測試一下,我所測試的文件是xxxAppDelegate.m,反彙編出來後:
"-[TestAppDelegate dealloc]":
LFB141:
LM5:
@ args = 0, pretend = 0, frame = 16
@ frame_needed = 1, uses_anonymous_args = 0
push {r7, lr}
LCFI3:
add r7, sp, #0
LCFI4:
sub sp, sp, #16
LCFI5:
str r0, [sp, #4]
str r1, [sp, #0]
LM6:
ldr r2, [sp, #4]
ldr r3, L19
L12:
add r3, pc
ldr r3, [r3, #0]
ldr r3, [r3, #0]
add r3, r2, r3
ldr r3, [r3, #0]
mov r2, r3
ldr r3, L19+4
L13:
add r3, pc
ldr r3, [r3, #0]
mov r0, r2
mov r1, r3
blx L_objc_msgSend$stub
LM7:
ldr r2, [sp, #4]
ldr r3, L19+8
L14:
add r3, pc
ldr r3, [r3, #0]
ldr r3, [r3, #0]
add r3, r2, r3
ldr r3, [r3, #0]
mov r2, r3
ldr r3, L19+12
L15:
add r3, pc
ldr r3, [r3, #0]
mov r0, r2
mov r1, r3
blx L_objc_msgSend$stub
LM8:
ldr r3, [sp, #4]
str r3, [sp, #8]
ldr r3, L19+16
L16:
add r3, pc
ldr r3, [r3, #0]
str r3, [sp, #12]
add r2, sp, #8
ldr r3, L19+20
L17:
add r3, pc
ldr r3, [r3, #0]
mov r0, r2
mov r1, r3
blx L_objc_msgSendSuper2$stub
LM9:
sub sp, r7, #0
pop {r7, pc}
然後,我們自己還可以做進一步測試,在變成Thumb的文件中插入一條代碼:
__asm__ volatile("sub r12, r6, r14");
單擊Build後會出現連接錯誤。而如果用
__asm__ volatile("add r12, r14");
則能通過連接和運行。而第一條代碼可以在其它ARM指令集下的源文件中正確地被編譯和連接。
下 面再談一下為何在Project Settings中需要-mno-thumb。這似乎是XCode的一個Bug,默認情況下GCC是使用ARM去編譯源文件的,但是當我設置好一個源文件 用Thumb去編譯時,所有文件都用Thumb去編譯了(難道還是本人RP太低),而在全局顯式的將這個thumb選項封住來規避這個Bug,呵呵。 |