一,前言
使用64位體系結(jié)構(gòu)對應(yīng)用程序的開發(fā)者來說,Solaris 64位操作系統(tǒng)和32位操作系統(tǒng)之間的最大差別在于它們使用的C語言數(shù)據(jù)類型模型。64位操作系統(tǒng)使用LP64模型,在LP64模型中l(wèi)ong類型和指針類型是64位的。其他基本數(shù)據(jù)類型和32位的模型一樣。32位數(shù)據(jù)類型使用ILP32模型,其中的int,long和指針類型都是32位的。下面列出了64位環(huán)境的主要特點(diǎn)和使用時(shí)需要考慮的問題。l 巨大的虛擬地址空間在64位環(huán)境中,一個(gè)進(jìn)程可以有多達(dá)64位寬的虛擬地址空間,或18 exabytes(18*260字節(jié))。這是32位環(huán)境中4G虛擬地址空間的四十億倍。由于硬件的限制,有的64位平臺(tái)無法完全支持64位的地址空間。大地址空間使得系統(tǒng)可以創(chuàng)建更多的線程,在32位平臺(tái)上一個(gè)缺省的線程需要1M堆棧,在64位平臺(tái)上一個(gè)缺省的線程需要2M堆棧。在32位平臺(tái)上可以創(chuàng)建4000個(gè)缺省線程,在64位平臺(tái)上可以創(chuàng)建8萬億個(gè)缺省線程。l 使用核心內(nèi)存的程序由于系統(tǒng)核心內(nèi)部也使用64位的數(shù)據(jù)結(jié)構(gòu),所以現(xiàn)存的程序,如果使用了libkvm,/dev/mem或/dev/kmem,將無法再在64位環(huán)境中運(yùn)行。必須將這樣的程序轉(zhuǎn)變?yōu)?4位的程序。l /proc的限制一個(gè)使用/proc的32位應(yīng)用程序可以訪問32位進(jìn)程的屬性,但無法訪問一個(gè)64位進(jìn)程的屬性;現(xiàn)存的描述進(jìn)程的接口和數(shù)據(jù)結(jié)構(gòu)不能包含所涉及的64位的量。這種程序必須重新編譯成64位應(yīng)用程序,這樣才能訪問32位和64位進(jìn)程的屬性。l 64位庫32位的應(yīng)用程序必須和32位的庫鏈接在一起,64位的應(yīng)用程序必須和64位的庫鏈接在一起。除了過時(shí)的庫,所有的庫都有32位和64位兩種版本。但沒有一個(gè)64位庫是靜態(tài)鏈接庫。l 64位運(yùn)算盡管在32位的Solaris系統(tǒng)中已經(jīng)有64位運(yùn)算了,但64位的實(shí)現(xiàn)為整數(shù)操作和參數(shù)傳遞提供了完全64位的機(jī)器寄存器。l 大文件如果一個(gè)程序只需要支持大文件,使用32位Solaris的大文件接口就可以了。但是為了充分的利用64位的優(yōu)點(diǎn),最好把程序轉(zhuǎn)變?yōu)?4位代碼。
64 位計(jì)算
Red Hat 和很多其它發(fā)行商為 Compaq/DEC Alpha 提供了一種 64 位版的 Linux。您可以在 AlphaLinux Web 站點(diǎn)上了解關(guān)于這種 Linux 的其它信息。64 位的 Solaris 和 64 位的 Linux/Alpha 都使用 LP64 數(shù)據(jù)模型,它能夠帶來很好的兼容性。
不久,Intel Itanium(TM) IA-64 處理器也能使用一種 64 位版的 Linux。您可以在 IA-64 Linux Project Web 站點(diǎn)了解關(guān)于這種 Linux 的更多信息。一種支持 IBM 64 位 PowerPC 體系結(jié)構(gòu)的 Linux 也在開發(fā)之中。
請注意,盡管 SuSE Linux/UltraSPARC 的內(nèi)核運(yùn)行在 64 位的模式中,但 SuSE Linux/UltraSPARC 目前并不支持 64 位的用戶空間應(yīng)用程序。
二,對于hp 32bit位 和64bit的區(qū)別
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
最主要的區(qū)別是long型和pointer型數(shù)據(jù)。
三,32bit機(jī)數(shù)據(jù)在內(nèi)容中的說明
A) 在為變量/對象分配內(nèi)存的時(shí)候,總是以4字節(jié)對齊,無論你的變量類型是什么。也就是說,任何一個(gè)變量/對象的存儲(chǔ)空間都是以4的整數(shù)倍的地址開始的。
B) 對于pointer型數(shù)據(jù),因?yàn)閮?nèi)容是地址,要求該地址也必須是4整數(shù)倍。
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型指針指向的內(nèi)容只能是1字節(jié)的數(shù)據(jù)。如果將
p->l賦更大的值22222,*(qq+7))只能取到地址為0x200000007ffff657
對應(yīng)的內(nèi)容)
printf("long ll l=%d\n",*(ll+1)); /*result =2*/
}
結(jié)構(gòu)體的內(nèi)存分配如下:
0x200000007ffff650: 0x00000001 0x00000002 0x00000000 0x00000000
0x200000007ffff660: 0x00000190 0x000002ec 0x000017a0 0x00000002
0x200000007ffff670: 0x00000000 0x00000000
圖解如下:
pp,qq,ll
Adress
data
0x200000007ffff650
00
0x200000007ffff651
00
0x200000007ffff652
00
0x200000007ffff653
01
0x200000007ffff654
l
00
0x200000007ffff655
00
0x200000007ffff656
00
0x200000007ffff657
02
0x200000007ffff658
0x200000007ffff659
0x200000007ffff65A
i
四,64bit機(jī)數(shù)據(jù)在內(nèi)容中的說明
A) 在為變量/對象分配內(nèi)存的時(shí)候,總是以8字節(jié)對齊,無論你的變量類型是什么。也就是說,任何一個(gè)變量/對象的存儲(chǔ)空間都是以8的整數(shù)倍的地址開始的。
B) 對于pointer型數(shù)據(jù),因?yàn)閮?nèi)容是地址,要求該地址也必須是8整數(shù)倍。
C) 例如:
main()
{
struct student
{
int i; /*8個(gè)字節(jié)的存儲(chǔ)空間,*/
long l; /*8個(gè)字節(jié)的存儲(chǔ)空間,*/
}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機(jī)下,內(nèi)存對齊的例子
正確:
int main()
{
long i;
char a[44];
long *p;
p=(char *)(a+8);
*p=3;
printf("*p=%d\n",*p); /*result = 3*/
}
錯(cuò)誤:
void main()
{
long i;
char a[44];
long *p;
p=a+4;
*p=3;
printf("*p=%d\n",*p); /*bus error*/
}
六,程序中的內(nèi)存分配淺談
一.存空間的對齊規(guī)則
首先看一段例子:
……
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";
……
輸出結(jié)果如下:
i1:0012FF4C
c1:0012FF48
c2:0012FF44
i2:0012FF40
是不是有些奇怪?
我們知道char類型的變量是只占用一個(gè)字節(jié)的,用sizeof(char)得到的結(jié)果也會(huì)是1。但在這里我們看到,c1和c2都被分配了4個(gè)字節(jié)的存儲(chǔ)空間,在32bit機(jī)下,在為變量/對象分配內(nèi)存的時(shí)候,總是以4字節(jié)對齊,無論你的變量類型是什么。也就是說,任何一個(gè)變量/對象的存儲(chǔ)空間都是以4的整數(shù)倍的地址開始的。64bit機(jī)下,都是8的倍數(shù)。
本文來自CSDN博客,轉(zhuǎn)載請標(biāo)明出處:http://blog.csdn.net/jiantiantian/archive/2008/12/17/3540923.aspx