一,前言<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
使用64位體系結構對應用程序的開發者來說,Solaris 64位操作系統和32位操作系統之間的最大差別在於它們使用的C語言數據類型模型。64位操作系統使用LP64模型,在LP64模型中long類型和指針類型是64位的。其他基本數據類型和32位的模型一樣。32位數據類型使用ILP32模型,其中的int,long和指針類型都是32位的。下面列出了64位環境的主要特點和使用時需要考慮的問題。l 巨大的虛擬地址空間在64位環境中,一個進程可以有多達64位寬的虛擬地址空間,或18 exabytes(18*260字節)。這是32位環境中4G虛擬地址空間的四十億倍。由於硬件的限制,有的64位平臺無法完全支持64位的地址空間。大地址空間使得系統可以創建更多的線程,在32位平臺上一個缺省的線程需要1M堆棧,在64位平臺上一個缺省的線程需要2M堆棧。在32位平臺上可以創建4000個缺省線程,在64位平臺上可以創建8萬億個缺省線程。l 使用核心內存的程序由於系統核心內部也使用64位的數據結構,所以現存的程序,如果使用了libkvm,/dev/mem或/dev/kmem,將無法再在64位環境中運行。必須將這樣的程序轉變爲64位的程序。l /proc的限制一個使用/proc的32位應用程序可以訪問32位進程的屬性,但無法訪問一個64位進程的屬性;現存的描述進程的接口和數據結構不能包含所涉及的64位的量。這種程序必須重新編譯成64位應用程序,這樣才能訪問32位和64位進程的屬性。l 64位庫32位的應用程序必須和32位的庫鏈接在一起,64位的應用程序必須和64位的庫鏈接在一起。除了過時的庫,所有的庫都有32位和64位兩種版本。但沒有一個64位庫是靜態鏈接庫。l 64位運算儘管在32位的Solaris系統中已經有64位運算了,但64位的實現爲整數操作和參數傳遞提供了完全64位的機器寄存器。l 大文件如果一個程序只需要支持大文件,使用32位Solaris的大文件接口就可以了。但是爲了充分的利用64位的優點,最好把程序轉變爲64位代碼。
64 位計算
Red Hat 和很多其它發行商爲 Compaq/DEC Alpha 提供了一種 64 位版的 Linux。您可以在 AlphaLinux Web 站點上了解關於這種 Linux 的其它信息。64 位的 Solaris 和 64 位的 Linux/Alpha 都使用 LP64 數據模型,它能夠帶來很好的兼容性。
不久,Intel Itanium(TM) IA-64 處理器也能使用一種 64 位版的 Linux。您可以在 IA-64 Linux Project Web 站點了解關於這種 Linux 的更多信息。一種支持 IBM 64 位 PowerPC 體系結構的 Linux 也在開發之中。
請注意,儘管 SuSE Linux/UltraSPARC 的內核運行在 64 位的模式中,但 SuSE Linux/UltraSPARC 目前並不支持 64 位的用戶空間應用程序。
二,對於hp 32bit位 和64bit的區別
hp C/HP-UX 32-bit and 64-bit base data types | ||
data type |
ILP32 size (bits) |
LP64 size (bits) |
char |
8 |
8 |
short |
16 |
16 |
int |
32 |
32 |
long |
32 |
64 |
long long (1) |
64 |
64 |
pointer |
32 |
64 |
float |
32 |
32 |
double |
64 |
64 |
long double |
128 |
128 |
enum (2) |
32 |
32 |
最主要的區別是long型和pointer型數據。
三,32bit機數據在內容中的說明
A) 在爲變量/對象分配內存的時候,總是以4字節對齊,無論你的變量類型是什麼。也就是說,任何一個變量/對象的存儲空間都是以4的整數倍的地址開始的。
B) 對於pointer型數據,因爲內容是地址,要求該地址也必須是4整數倍。
C) 例如:
main()
{
struct student
{
int i;
long l;
}node;
struct student *p;
p=&node;
int *pp;
char *qq;
long *ll;
p->i=1;
p->l=2;
pp=(int *)p;
qq=(char *)p;
ll=(long *)p;
printf("int pp l=%d/n",*(pp+1)); /*result =2*/
printf("char qq l=%d/n",*(qq+7)); /*result =2*/
(char型指針指向的內容只能是1字節的數據。如果將
p->l賦更大的值22222,*(qq+7))只能取到地址爲0x200000007ffff657
對應的內容)
printf("long ll l=%d/n",*(ll+1)); /*result =2*/
}
結構體的內存分配如下:
0x200000007ffff650: 0x00000001 0x00000002 0x00000000 0x00000000
0x200000007ffff660: 0x00000190 0x000002ec 0x000017a0 0x00000002
0x200000007ffff670: 0x00000000 0x00000000
圖解如下:
<?xml:namespace prefix = v ns = "urn:schemas-microsoft-com:vml" />
|
data | |
0x200000007ffff650 |
00 | |
0x200000007ffff651 |
00 | |
0x200000007ffff652 |
00 | |
0x200000007ffff653 |
01 | |
0x200000007ffff654 |
| |
0x200000007ffff655 |
00 | |
0x200000007ffff656 |
00 | |
0x200000007ffff657 |
02 | |
0x200000007ffff658 |
| |
0x200000007ffff659 |
| |
0x200000007ffff65A |
|
i |
四,64bit機數據在內容中的說明
A) 在爲變量/對象分配內存的時候,總是以8字節對齊,無論你的變量類型是什麼。也就是說,任何一個變量/對象的存儲空間都是以8的整數倍的地址開始的。
B) 對於pointer型數據,因爲內容是地址,要求該地址也必須是8整數倍。
C) 例如:
main()
{
struct student
{
int i; /*8個字節的存儲空間,*/
long l; /*8個字節的存儲空間,*/
}node;
struct student *p;
p=&node;
int *pp;
char *qq;
long *ll;
p->i=1;
p->l=222222222;
pp=(int *)p;
qq=(char *)p;
ll=(long *)p;
printf("int pp l=%d/n",*(pp+2));/*result int pp l=222222222*/
printf("char qq l=%d/n",*(qq+15));/*result int pp 13*/
printf("long ll l=%d/n",*(ll+1));/*result int pp l=222222222*/
}
五,64bit機下,內存對齊的例子
正確:
int main()
{
long i;
char a[44];
long *p;
p=(char *)(a+8);
*p=3;
printf("*p=%d/n",*p); /*result = 3*/
}
錯誤:
void main()
{
long i;
char a[44];
long *p;
p=a+4;
*p=3;
printf("*p=%d/n",*p); /*bus error*/
}
六,程序中的內存分配淺談
一.存空間的對齊規則
首先看一段例子:
……
int i1;
char c1;
char c2;
int i2;
cout << "i1:" <<&i1 << "/n";
cout << "c1:" <<(void *)&c1 << "/n";
cout << "c2:" <<(void *)&c2 << "/n";
cout << "i2:" <<&i2 << "/n";
……
輸出結果如下:
i1:0012FF4C
c1:0012FF48
c2:0012FF44
i2:0012FF40
是不是有些奇怪?
我們知道char類型的變量是隻佔用一個字節的,用sizeof(char)得到的結果也會是1。但在這裏我們看到,c1和c2都被分配了4個字節的存儲空間,在32bit機下,在爲變量/對象分配內存的時候,總是以4字節對齊,無論你的變量類型是什麼。也就是說,任何一個變量/對象的存儲空間都是以4的整數倍的地址開始的。64bit機下,都是8的倍數。