结构体对齐

我理解的结构体对齐,对于64位的,起址要8字节对齐.这个编译器可以默认帮你完成,你不必在之前加align 8.

结构体内部的对齐可以由两种方式实现:
1.
*** STRUCT  alignment


*** ENDS
其中alignment 可以为1,2,4,8等。
2.
编译时加一个命令: -Zp[n]    这里的n与上面的alignment等效.
比如8字节对齐,可以加上 -Zp8
或用
*** STRUCT  8


*** ENDS

如果同时使用了这两种方式,则*** 结构体仍以alignment为对齐原则,其它的未指定的以-Zp[n]对齐.

所以通常加个-Zp[n] 全局结构体对齐就可以了.

可要注意到,-Zp[n]的n仅仅是一个建议值,它是以min{max{sizeof(结构体元成员的类型)},n}为原则.
比如:
指定了: -Zp8   (即n=8)
则对于:
RECT struct
    left    dd     ?
    top     dd     ?
    right   dd     ?
    bottom  dd     ?
RECT ends
均以4字节对齐,因为 min{max{sizeof(DWORD)},8}=4.

又如:
我们定义了一个64位编程中的MSG结构.
指定了: -Zp8   (即n=8)
MSG struct
  hwnd      dq      ?
  message   dd      ?
  wParam    dq      ?
  lParam    dq      ?
  time      dd      ?
  pt        POINT   <>
MSG ends
则以上MSG结构以8字节对齐,因为 min{max{sizeof(dq)},8}=8.

这个对齐工作是由编译器帮你完成的.而不用你自己实现对齐,形如:
MSG struct
  hwnd       dq      ?
  message    dd      ?
  padding1   dd      ?      ;message成员变量是4字节,所以要填充一个4字节变量
  wParam     dq      ?
  ......
MSG ends
是不必要的.

==============================
总结上面的对齐原则:

对于win32  默认即可,而对于win64至少加上-Zp8对齐,否则对于有>4字节的类型变量时会出错.
或许对于ml64.exe也可以默认,因为它是这么做的.而JWasm则必须加上.

==============================
对于x86或x64 在windows.inc中常量是通用的.
所以我们可以做些小改变,即可实现win32/64的同一inc文件,同一源文件的统一编程.

masm32中的windows.inc 及其它定义未把指针与DWORD数据相区分.

所以我们可以这样来定义:
IFNDEF X64_INC
X64_INC equ <0>
ENDIF

IF X64_INC eq 1
  WPARAM    typedef QWORD
  LPARAM    typedef QWORD
  LPSTR     typedef QWORD

ELSE
  WPARAM    typedef DWORD
  LPARAM    typedef DWORD
  LPSTR     typedef DWORD
ENDIF


POINT STRUCT
  x  DWORD ?
  y  DWORD ?
POINT ENDS

MSG STRUCT
  hwnd      LPSTR      ?
  message   DWORD      ?
  wParam    WPARAM     ?
  lParam    LPARAM     ?
  time      DWORD      ?
  pt        POINT      <>
MSG ENDS

WM_CLOSE               equ 10h
WM_COMMAND             equ 111h
WM_SIZE                equ 5h
WM_PAINT               equ 0Fh
WM_DESTROY             equ 2h

;.....

 

 


 

你可能感兴趣的:(编程,工作,struct,command,编译器,alignment)