現在我們開發的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,呵呵。 |