返回列表 回復 發帖

在iPhone App中使用Thumb指令集

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