首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 組合語言

組合語言 LEA 指令進階用法:替代乘法運算與位址計算最佳化

     編輯:組合語言

前言

LEA (Load Effective Address) 原本用於計算記憶體操作數的有效位址,但因其能在單指令中完成「基址 + 索引×比例 + 位移」的算術運算,且不存取記憶體、不影響旗標,成為替代 MUL/SHL/ADD 序列的高效最佳化指令。

LEA 運算公式


LEA REG, [BASE + INDEX*SCALE + DISP]
; 計算結果 = BASE + INDEX×SCALE + DISP → 存入 REG
; SCALE ∈ {1, 2, 4, 8}
; 不存取記憶體,不影響任何旗標

替代乘法的經典範例

目標運算傳統指令序列LEA 最佳化優勢
EAX * 2SHL EAX, 1 / ADD EAX, EAXLEA EAX, [EAX*2]不影響 CF/OF
EAX * 3LEA EAX, [EAX*2+EAX]LEA EAX, [EAX*2+EAX]單指令
EAX * 4SHL EAX, 2LEA EAX, [EAX*4]不影響旗標
EAX * 5LEA EAX, [EAX*4+EAX]LEA EAX, [EAX*4+EAX]單指令
EAX * 8SHL EAX, 3LEA EAX, [EAX*8]不影響旗標
EAX * 9LEA EAX, [EAX*8+EAX]LEA EAX, [EAX*8+EAX]單指令
EAX * 10LEA EAX, [EAX*8+EAX*2]LEA EAX, [EAX*8+EAX*2]單指令

原文範例


; EAX * 5
LEA EAX, [EAX*4 + EAX]   ; 比 MUL 快得多

位址計算與陣列索引


; 結構陣列: MYSTRUCT 大小 24 位元組
; 取得第 ECX 個元素的欄位 OFFSET_FIELD 位址
LEA EAX, [ArrayBase + ECX*24 + OFFSET_FIELD]
; 單指令完成: 基址 + 索引×結構大小 + 欄位偏移

組合多項式運算


; 計算 3*EAX + 5*EBX + 10
LEA EAX, [EAX*2 + EAX]       ; EAX *= 3
LEA EBX, [EBX*4 + EBX]       ; EBX *= 5
LEA EAX, [EAX + EBX*1 + 10]  ; 合併 (SCALE=1 即不寫)

限制與注意事項

  • SCALE 僅限 1, 2, 4, 8:無法直接計算 ×3, ×5, ×6, ×7, ×9 等,需組合 (如 [EAX*2+EAX] = ×3)。
  • 不支援除法:除法仍需 DIV/IDIV 或乘以倒數近似。
  • 不影響旗標:若後續需依據乘法結果旗標 (如 CF 判斷溢位),LEA 無法提供,需改用 MUL/IMUL。
  • 目的暫存器限制:16/32 位模式下目的為 16/32 位通用暫存器;64 位模式下可為 64 位暫存器。

效能比較 (現代微架構)

結論:LEA 在常數乘法、位址計算上通常優於或持平 IMUL/SHL+ADD,且不破壞旗標,是最佳化關鍵路徑的首選。

總結

LEA 不只是載入位址指令,更是一個「免費的算術單元」。善用 [BASE + INDEX*SCALE + DISP] 編碼形式,可將常數乘法 (×2,3,4,5,8,9...)、結構陣列索引、多項式合併濃縮為單指令,同時保留旗標狀態。熟練掌握 LEA 最佳化模式,是組合語言高效能程式設計的標誌性技能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
指令延遲吞吐微操作數
LEA (2 操作數)1 cycle0.5-1/cycle1
LEA (3 操作數, 基址+索引×比例+位移)3 cycles1/cycle1-2
IMUL REG, REG, IMM3 cycles1/cycle1
SHL/ADD 序列1-2 cycles1-2/cycle2-3