[英]Must the first operand of leaq be a memory address and the second operand be a register?
在ATT匯編語言中,當使用leaq指令時,其第一個操作數必須是內存地址,而不是寄存器或常量(前綴$
)嗎? 它的第二個操作數必須是一個寄存器嗎? 通過閱讀《計算機系統:程序員的觀點》,我得到了這種印象,並且從未見過與我的猜測不同的示例。 謝謝。
即使它是可編碼的,您也永遠不會想要使用它。
如果要在寄存器中放入常量,則永遠不要使用lea
。 mov $1234, %eax
比lea 1234, %eax
(disp32尋址模式下的絕對地址)更短,更高效。
LEA靜態地址的唯一用例是具有RIP相對尋址模式的64位代碼,例如lea symbol(%rip), %rax
(7個字節),在mov $symbol, %eax
(5個字節)的情況下無法使用,因為您需要與位置無關的代碼,並且/或者地址不適合32位零擴展立即數。
有關為何mov $symbol, %rdi
不是最佳選擇的更多信息,請參見x86-64中的movq和movabsq之間的區別 。
在32位代碼lea symbol, %edi
為6個字節(操作碼+ modrm + disp32),並且僅在Intel Sandybridge系列CPU上運行一個端口1或端口5。 ( https://agner.org/optimize/ )
mov $symbol, %edi
是5個字節( 操作碼+ imm32簡短形式,無ModRM字節 ),並且可在任何ALU端口上運行。
對於16位代碼相同: mov $symbol, %di
是3個字節,而lea symbol, %di
是4個字節,具有相同的執行端口差異。 (或使用NASM語法,GAS .intel_syntax
或MASM中的lea di, [symbol]
與mov di, symbol
或mov di, OFFSET symbol
)。
不過,LEA在base = register尋址模式下很有用。 與lea symbol(%rdi), %rax
如果地址適合32位符號擴展的disp32 lea symbol(%rdi), %rax
。
或對於任意移位和加法用法,例如lea 123(%rdi, %rdi, 2), %eax
做eax = 3*edi + 123
。 在不是地址/指針的值上使用LEA嗎?
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.