iOS應用如何實現64位的支援

2021-06-27 17:20:43 字數 3229 閱讀 1578

關於指令集如下參考:

armv8/arm64: iphone 6(plus), iphone 5s, ipad air(2), retina ipad mini(2,3)

armv7s: iphone 5, iphone 5c, ipad 4

armv7: iphone 3gs, iphone 4, iphone 4s, ipod 3g/4g/5g, ipad, ipad 2, ipad 3, ipad mini

armv6: iphone, iphone 3g, ipod 1g/2g

對於支援64-bit,我們可以設定architectures為 standard architectures,在最新的xcode 6上,它包括 armv7和arm64。

64-bit執行時環境和32-bit執行時環境主要有以下兩點的不同:

整型資料型別的變化如下:

浮點型型別的改變如下:

資料型別的改變可能會為我們的程式帶來這些影響:

基於32-bit的cpu和基於64-bit上的cpu有不同數量的暫存器,在方法呼叫上有不同的協議。因此32-bit和64-bit在彙編層級上是不同的。如果我們在程式中不使用彙編程式設計,呼叫協議很少會遇到。

在llvm編譯器中,列舉型別也可以定義列舉的大小。我們在使用中,指派列舉值到乙個變數時,應該使用適當的資料型別。

int a = 5;

int *c = &a;

/* 32-bit下正常,64-bit下錯誤。最新的xcode6.0編譯提示警告:'cast to int* for smaller integer type int'*/

int *d = (int *)((int)c + 4);

/* 正確, 指標可以直接增加*/

int *d = c + 1;

如果我們一定要把指標轉化為整型,可以把上述**改為:

/* 32-bit和64-bit都正常。*/

int *d = (int *)((uintptr_t)c + 4);

檢視uintptr_t定義為 typedef unsigned long uintptr_t;

在32-bit和64-bit下,fpos_t和off_t都是64 bits的資料大小,永遠不要把它們指向int整型。

long performcalculation(void);

int c = performcalculation(); // 錯誤 64-bit上資料將被擷取

long y = performcalculation(); // 正確

int performanothercalculation(int input);

long i = long_max;

int x = performcalculation(i); // 錯誤

int returnmax()

nsinteger : 在32-bit和64-bit下有分別的定義:

#if __lp64__ || (target_os_embedded && !target_os_iphone) || target_os_win32 || ns_build_32_like_64

typedef long nsinteger;

#else

typedef int nsinteger;

#endif

我們永遠不應該假設nsinteger和int是一樣大的,下面的例子在使用中就需要注意:

cgfloat: 和nsinteger一樣有不同的定義

typedef cgfloat_type cgfloat;

#if defined(__lp64__) && __lp64__

# define cgfloat_type double

#else

# define cgfloat_type float

#endif

下面給出錯誤示範:

cgfloat value = 200.0;

cfnumbercreate(kcfallocatordefault, kcfnumberfloattype, &value); //64-bit下出現錯誤

cgfloat value = 200.0;

cfnumbercreate(kcfallocatordefault, kcfnumbercgfloattype, &value); //正確

關於c語言的符號位擴充套件可參考資料為:

我們直接來看例子:

int a = -2;

unsigned int b = 1;

long c = a + b;

long long d = c;

printf("%lld\n", d);

問題:這段**在32-bit下執行結果符合我們的預期,輸出為 -1(0xffffffff)。在64-bit下執行結果為:4294967295 (0x00000000ffffffff)。

原因:乙個有符號的值和乙個同樣精度的無符號的值相加結果是無符號的。這個無符號的結果被轉換到更高精度的數值上時採用零擴充套件。

解決方案:把變數b換成長整型long

c99提供了內建的資料型別保證了一致的資料大小,即使底層的硬體結構不同。在某些case下,我們知道資料是乙個固定的大小或者乙個特定的變數擁有乙個有限的取值範圍。這個時候,我們應該選擇特定的型別以避免浪費記憶體。

型別如下:

永遠不要使用malloc去為變數申請特定記憶體的大小,改為使用sizeof來獲取變數或者結構體的大小。

另外我們還需要注意修改格式化字串來同時支援32-bit和64-bit。

int fixedfunction(int a, int b);

int variadicfunction(int a, ...);

int main

上述兩個方法中,在32-bit下使用相同的指令讀取引數的資料,但是在64-bit上,是使用完全不同的協議來編譯的。

如果在**中傳遞方法指標,應該保證方法呼叫的協議是一致的。永遠不要將乙個可變引數的方法轉化成固定引數的方法。

int myfunction(int a, int b, ...);

int (*action)(int, int, int) = (int (*)(int, int, int)) myfunction;

action(1,2,3); // 錯誤示範

iOS應用如何實現64位的支援

關於指令集如下參考 armv8 arm64 iphone 6 plus iphone 5s,ipad air 2 retina ipad mini 2,3 armv7s iphone 5,iphone 5c,ipad 4 armv7 iphone 3gs,iphone 4,iphone 4s,ipo...

iOS應用如何實現64位的支援

關於指令集如下參考 armv8 arm64 iphone 6 plus iphone 5s,ipad air 2 retina ipad mini 2,3 armv7s iphone 5,iphone 5c,ipad 4 armv7 iphone 3gs,iphone 4,iphone 4s,ipo...

iOS 中支援64位操作

現在5s初到64位了,以前打的包好多都會報錯 ignoring file users why desktop phonefax umsocial sdk 3.1 libumsocial sdk 3.1.a,missing required architecture x86 64 in file us...