32 位的寄存器容量是 4 字節, 如果內存中的數據都按 4*n 字節對齊, 肯定會加快吞吐速度;
但事實並非如此, 不同大小的數據可能會讓寄存器別別扭扭地去處理, 從而降低了運行速度!
如果使用對齊, 就會浪費掉一些內存空間; 其實這是一個需要權衡 "速度" 與 "內存" 得失的問題.
准備使用的測試文件:
; Test11_1.asm
.586
.model flat, stdcall
include Windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
;聲明三個字節變量
v1 db 0
v2 db 0
v3 db 0
.code
main proc
;三個字節變量的默認偏移地址如下(在沒有對齊約束的情況下, 它們各占一個字節):
PrintDec offset v1 ;4206592
PrintDec offset v2 ;4206593
PrintDec offset v3 ;4206594
ret
main endp
end main
ALIGN: 指定對齊邊界
; Test11_2.asm
.586
.model flat, stdcall
include Windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
v1 db 0
align 4 ;讓下一個變量的起始地址保證是 4 的倍數
v2 db 0
v3 db 0
.code
main proc
PrintDec offset v1 ;4206592
PrintDec offset v2 ;4206596 (!)
PrintDec offset v3 ;4206597
ret
main endp
end main
;align 後面的參數是 2n, 還可測試下: 1、2、8、16
EVEN 相當於 ALIGN 2
; Test11_3.asm
.586
.model flat, stdcall
include Windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
v1 db 0
even ;(!)
v2 db 0
v3 db 0
.code
main proc
PrintDec offset v1 ;4206592
PrintDec offset v2 ;4206594 (!)
PrintDec offset v3 ;4206595
ret
main endp
end main
ORG 可以指定從當前位置跨越指定書目的字節再安排下一個數據:
; Test11_4.asm
.586
.model flat, stdcall
include Windows.inc
include kernel32.inc
include masm32.inc
include debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib
.data
v1 db 0
org 100 ;(!)
v2 db 0
v3 db 0
.code
main proc
PrintDec offset v1 ;4206592
PrintDec offset v2 ;4206692 (!)
PrintDec offset v3 ;4206693
ret
main endp
end main
這些偽指令不對局部變量產生影響, 因為偽指令作用在編譯之前, 局部變量使用內存是程序運行之後的事.
關於局部變量的對齊和速度, 除了編譯的工作外, 我們在安排變量類型和次序時也應該考慮到 "對齊" 的問題.