32位程式移植到64位需要考慮的問題

2021-06-27 13:15:16 字數 2322 閱讀 5396

(翻譯自:

概述

從32位到64位,根本性的區別在於兩種資料型別發生了變化:long和pointer。在32位環境下,顧名思義,兩者長度都是32位,也就是4個位元組;而在64位環境下,都是8個位元組。所以,當你把pointer或者long型資料賦給int型時,會發生資料截斷(data truncation)。

32位與64位資料模型之間的區別

32位應用的資料模型我們稱作ilp32(之所以這樣命名,是因為int,long,pointer都是32位),而64位應用則採用lp64模型(意味著long,pointer變成64位了,其他的不變),在當前的32位環境下,我們可以認為int,long,pointer是等價的,因為它們占用相同的位元組嘛,於是,就有很多混用的情況;但是,到了64位的時代,long和poniter的大小都改變了,原來的假設不再成立。

用lint檢測long/pointer的64位問題

採用-errchk=longptr64選項可以檢查出把long/pointer表示式轉換為int的情況,包括顯式轉換。

留心int和pointer

因為integer與pointer大小相同,所以32位**中常常把pointer轉換為int或者unsigned int,以便算術運算。為了移植,你可以把pointer轉換為unsigned long,因為long和pointer都是等長的,無論是在ilp32亦或lp64,但是,為了使**更清晰,推薦用uintptr_t,uintptr_t和intptr_t都需要包含標頭檔案inttypes.h。

例如:下面**在64位環境下編譯出錯:

char *p;

p = (char *) ((int)p & pageoffset);

% cc ..

warning: conversion of pointer loses bits

改用uintptr_t後,無論是32位或者64位都沒問題:

char *p;

p = (char *) ((uintptr_t)p & pageoffset);

留心int和long

在ilp32中,可能從未對int和long加以區分,因此,混用的情況非常多,看下面**:

int waiting;

long w_io;

long w_swap;

...waiting = w_io + w_swap;

% cc

warning: assignment of 64-bit integer to 32-bit integer

留心對齊

出於訪問的效率,結構中通常會有所謂的hole,用來保證其中的所有資料成員,起始位址都是對齊模數的倍數。

例如:struct bar ;

在ilp32中,sizeof(bar)應該是16位元組;在lp64中,應該是32!因為此時long/char *的對齊模數都變為8,為了保證滿足對齊要求,i/k都被擴充套件為8位元組了。

又例如:

struct bar

此時,無需擴充套件,sizeof(bar)=8+8+4+4=24.

留心union

union中的成員,必須保持平衡,也就是說,必須保證大小相等才有意義,所以移植時也要注意。

例如:typedef union llx_

在ilp32中,兩者大小相同,都是8位元組;移植到lp64,前者不變,後者為16位元組,此時union已無意義,應改為:

typedef union llx_

留心常量型別

在常量表示式中,精度的缺失會導致資料截斷,例如:

int i = 32;

long j = 1 << i;

warning: left shift count >= width of type

什麼意思?編譯器抱怨左移的位數超過了資料型別的長度,結果就是j為0。

怎麼修改呢?

int i = 32;

long j = 1l << i:

即可。留心printf系列函式

在格式化串中,要注意:

%p相容ilp32和l64。

如果有long型引數,必須加上l字首;

另外就是作為目標的buffer必須夠長。

留心sizeof

sizeof返回型別為unsigned long,如果返回給int型變數,可能發生截斷。

留心derived data types

32位程式移植到64位平台前的準備工作

32位程式移植到64位平台前的準備工作 2006 02 13 09 18 46 我來說兩句 收藏 我要投稿 字型 小大 我們最近完成的乙個專案是移植乙個大型的32位應用程式,它可在64位環境中支援11個作業系統平台,並且程式的源 超過了30萬行。由於此32位程式是在幾年前分成幾部分開發而成,所以極有...

64位系統編譯32位程式

如上使用c4這個小工具時遇到來需要 32位系統的需求,發現使用 m32引數後,編譯提示錯誤,如下 usr bin ld 未知的 模式 32 支援的 elf x86 64 elf32 x86 64 elf i386 i386linux elf l1om elf k1om i386pep i386pe ...

32位和64位程式的區別

由於作業系統記憶體分配的不同,導致軟體開發過程中,需要編譯不同版本的軟體,此處以vs為例。1 編譯程式根據需要選擇不同的編譯環境 x86和win32位32位程式,x64為64位程式,可以選擇不同的編輯條件形成不同位的軟體。2 中的基本的資料型別,會根據作業系統的位數分配記憶體大小 如int型在32位...