一,前言
使用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
圖解如下:
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機數據在內容中的說明
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的倍數。
本文來自CSDN博客,轉載請標明出處:http://blog.csdn.net/jiantiantian/archive/2008/12/17/3540923.aspx