本文將系統地介紹如何利用XCode在iOS裝置上使用組合語言。
一、建立彙編源檔案:
在你的XCode項目中存放源檔案的目錄下滑鼠(或觸控板)右鍵,選擇New File。然後在左側的iOS那欄裡選擇Other,在右邊你會看到Assembly File,選中它,然後命名,以.s作為尾碼。
二、編寫彙編代碼:
然後可以嘗試以下代碼:
/*
* arm7.asm
* Test
*
* Created by Zenny Chen on 4/24/10.
* Copyright 2010 GreenGames Studio. All rights reserved.
*/
.text
.align 4
.globl _my_arm_test
.globl _my_thumb_test
.arm
_my_arm_test:
vdup.32 q0, r0
qadd8 r0, r1, r2
add r0, r0, LSL #2
bx lr
.thumb
.thumb_func _my_thumb_test
_my_thumb_test:
movw r1, #1001
rev16 r0, r1
bx lr
這裡要注意的是Apple所採用的ARM彙編器遵循GNU Assembler規範。其中,我們可以看到,彙編檔案裡的注釋可以採用C語言標準的注釋方式,也可以用C++標準的//注釋方式。
.text表示代碼本文部分。
.align根據不同的彙編器會有不同的行為,像這裡的.align4可能表示4位元組對齊,也可能表示16位元組對齊。
GAS規範中表示,可以用.global或.globl來標註全域函數。在Apple的Assembler中僅支援.globl。函數名前要加底線。
.arm表示後面的函數中的指令都是arm指令。而.thumb表示後面函數中的指令都是thumb或thumb-2指令。其中,如果一個函數是用thumb寫的,那麼必須用.thumb_func修飾,否則連接器在串連符號時會有問題。
上述代碼中,_my_arm_test分別使用了一條NEON指令,一條ARMv6指令和兩條ARMv5TE指令。而_my_thumb_test中則分別使用了一條ARMv7 Thumb-2指令、一條ARMv6指令和一條ARMv5TE指令。
另外,Apple LLVM彙編器中的條件預先處理與C語言用的也幾乎一樣。可以使用#if、#else、#endif、#ifdef、#ifndef、#elif等等。另外,在架構標識上也統一使用了標準的架構標識符,比如:__i386__表示x86處理器架構;__x86_64__表示64位的x86處理器;__arm__表示ARM架構的處理器。下面給出一個範例程式碼:
.text.align 2.globl _MyASMTest#if defined(__i386__) || defined(__x86_64__)_MyASMTest: xor %eax, %eax ret#elif defined(__arm__)_MyASMTest: eor r1, r0, r0 bx lr#endif
三、在C/C++或Objective C/C++中調用彙編函數
如何在你的C/C++源檔案中調用彙編寫的函數呢?其實這跟調用普通的C函數一樣。
extern int my_arm_test(int a, int b, int c);extern int my_thumb_test(int a, int b);void my_test(void){ printf("ARM value: %d\n", my_arm_test(10, 20, 30)); printf("Thumb value: %d\n", my_thumb_test(10, 20));}
我們可以看到,這裡函數名前的底線沒有了。這裡不需要,而且也不能加底線。
由於當前Apple的ARM彙編器尚未完全支援Thumb-2指令集,像.w尾碼就全都沒有支援。但Apple LLVM3.0和LLVM-GCC支援。因此我們可以採用在C/C++中以內聯彙編的方式來寫。詳細請參考——在LLVM的C語言編譯器中內聯純彙編函數的注意事項。