程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Delphi >> 學 Win32 匯編 [11]: 數據對齊相關的偽指令(ALIGN、EVEN、ORG)

學 Win32 匯編 [11]: 數據對齊相關的偽指令(ALIGN、EVEN、ORG)

編輯:Delphi

 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 

  這些偽指令不對局部變量產生影響, 因為偽指令作用在編譯之前, 局部變量使用內存是程序運行之後的事.

  關於局部變量的對齊和速度, 除了編譯的工作外, 我們在安排變量類型和次序時也應該考慮到 "對齊" 的問題.


  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved