Windows 32、64位系统编译器各数据类型大小和字节对齐关系
2023-09-11 14:15:13 时间
何为32位64位?
32位64位其实就是32bit 64bit ,32位cpu单次处理指令4字节,64位8字节,因为1字节=1byte=8bit(32/8=4字节,64/8=8字节)
32位编译器:32位系统下指针占用4字节
64位编译器:64位系统下指针占用8字节
struct结构体成员中对齐关系:
字节对齐的细节和具体编译器实现相关,但一般而言,需满足以下四个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
4)结构体作为数据成员的对齐规则:在一个struct中包含另一个struct,内部struct应该以它的最大数据成员大小的整数倍开始存储
随便贴几个32/64相同结构体字节对齐填充示例:
{32位}
_UNICODE_STRING = packed record
Length : USHORT;
MaximumLength : USHORT;
Buffer : PWideChar;
end;
UNICODE_STRING = _UNICODE_STRING;
PUNICODE_STRING =^_UNICODE_STRING;
{64位}
_UNICODE_STRING64 = packed record
Length : USHORT; //USHORT=2字节
MaximumLength : USHORT;
Fill : DWORD; //填充4字节对齐
Buffer : ULONG64;//ULONG64; //PVOID64
end;
UNICODE_STRING64 = _UNICODE_STRING64;
PUNICODE_STRING64 =^_UNICODE_STRING64;
{32位}
PLDR_DATA_TABLE_ENTRY = ^LDR_DATA_TABLE_ENTRY;
LDR_DATA_TABLE_ENTRY = packed Record
InLoadOrderModuleList:LIST_ENTRY;
InMemoryOrderModuleList:LIST_ENTRY;
InInitializationOrderModuleList:LIST_ENTRY;
BaseAddress:Cardinal;
EntryPoint:Cardinal;
SizeOfImage:Cardinal;
FullDllName:UNICODE_STRING;
BaseDllName:UNICODE_STRING;
Flags:Cardinal;
LoadCount:Word;
TlsIndex:Word;
SectionHandle:Cardinal;
CheckSum:Cardinal;
TimeDateStamp:Cardinal;
end;
{64位}
PLDR_DATA_TABLE_ENTRY64= ^LDR_DATA_TABLE_ENTRY64;
LDR_DATA_TABLE_ENTRY64 = packed record
InLoadOrderModuleList:LIST_ENTRY64;//PVOID64;//LIST_ENTRY;
InMemoryOrderModuleList:LIST_ENTRY64;//PVOID64;//LIST_ENTRY;
InInitializationOrderModuleList:LIST_ENTRY64;//PVOID64;//LIST_ENTRY;
BaseAddress:ULONG64;
EntryPoint:ULONG64;
SizeOfImage:ULONG64;//ULONG; //8字节对齐
FullDllName:UNICODE_STRING64;
BaseDllName:UNICODE_STRING64;
Flags:ULONG;
LoadCount:USHORT;
TlsIndex:USHORT;
end;
{32位}
PPEB_LDR_DATA =^PEB_LDR_DATA;
PEB_LDR_DATA = packed record
Len:Cardinal;
Initialized:Bool;
SsHandle:PPointer;
InLoadOrderModuleList:LIST_ENTRY;
InMemoryOrderModuleList:LIST_ENTRY;
InInitializationOrderModuleList:LIST_ENTRY;
end;
{64位}
PPEB_LDR_DATA64= ^PEB_LDR_DATA64;
PEB_LDR_DATA64 = packed record
Length:ULONG; //4Byte
Initialized:BOOLEAN; //1Byte
Reserved1: array [0..2] of Byte; //3Byte 补3字节填充跟前面一起凑成8字节
SsHandle:ULONG64; //8Byte
InLoadOrderModuleList:LIST_ENTRY64; // PVOID64
InMemoryOrderModuleList:LIST_ENTRY64;
InInitializationOrderModuleList:LIST_ENTRY64;
EntryInProgress:ULONG64;
end;
{32位}
PPEB = ^PEB;
PEB = packed record
Reserved1: array[0..1] of Byte;
BeingDebugged: ByteBool;
Reserved2: Byte;
Reserved3: array[0..1] of Pointer;
Ldr: PPEB_LDR_DATA; //Pointer
ProcessParameters: PRTL_USER_PROCESS_PARAMETERS;
Reserved4: array[0..103] of Byte;
Reserved5: array[0..51] of Pointer;
end;
{64位}
PPEB64 = ^PEB64;
PEB64 = packed record
InheritedAddressSpace : UCHAR; //1 Byte
ReadImageFileExecOptions : UCHAR;
BeingDebugged: UCHAR;
BitField: UCHAR;
Reserved1:DWORD; //因为64位系统是8字节对齐,所以补4位,跟前面4个uchar一起凑成8字节
Mutant:ULONG64; //编译器问题,VC++不用补位,实测VS2017,VS2015中编译器貌似会自动填充对齐
ImageBaseAddress: ULONG64;
Ldr:PVOID64; //PPEB_LDR_DATA64; //ULONG64;
ProcessParameters:PVOID64;//PRTL_USER_PROCESS_PARAMETERS64; // ULONG64;
SubSystemData: ULONG64;
ProcessHeap: ULONG64;
FastPebLock: ULONG64;
AtlThunkSListPtr:ULONG64;
IFEOKey: ULONG64;
CrossProcessFlags: ULONG64;
UserSharedInfoPtr: ULONG64;
SystemReserved: ULONG;
AtlThunkSListPtr32:ULONG;
ApiSetMap: ULONG64;
end;
Delphi中32位64位程序在64位系统下各数据类型占用字节统计如下:
具体字节对齐填充原理可以参考此连接:
原创文章,转载请注明出处!谢谢
相关文章
- 系统管理员已经限制你可以使用的登录类型(网络或交互式) - Windows远程报错的解决方案汇总
- USB设备不能用。提示Windows 无法启动这个硬件设备。 (代码 19)
- perl 在windows上获取当前桌面壁纸
- Windows下 Python 安装包的配置
- windows自定义快捷键功能
- MFC Windows 程序设计[234]之重复文件搜索工具(附源码)
- MFC Windows 程序设计[三十四]之条码型字体
- .NET Core多平台开发体验[3]: Linux (Windows Linux子系统)
- windows 安装cygwin教程
- [手游项目5]windows获得当前进程名
- QT里实现Windows电脑三种关机方法
- chromium在windows上的编译 构建 Checking out and Building Chromium for Windows
- windows_libpytorch
- python在windows通过安装模块错误
- Windows下用Eclipse搭建C/C++开发环境
- windows与Ubuntu实现文件夹共享
- windows下,‘make‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。