[英]How do I negate a 64-bit integer stored in a 32-bit register pair?
我在EDX:EAX
寄存器對中存儲了一個64 位整數。 我怎樣才能正確否定這個數字?
例如: 123456789123
→ -123456789123
。
向編譯器int64_t neg(int64_t a) { return -a; }
意見: compile int64_t neg(int64_t a) { return -a; }
int64_t neg(int64_t a) { return -a; }
在 32 位模式下。 當然,詢問編譯器的不同方式將在內存中、在編譯器選擇的寄存器中或已經在 EDX:EAX 中具有起始值。 在 Godbolt 編譯器資源管理器上查看所有三種方式,以及來自 gcc、clang 和 MSVC(又名 CL)的 asm 輸出。
當然有很多方法可以實現這一點,但任何可能的序列在某個時候都需要某種從低到高的進位,因此沒有有效的方法來避免 SBB 或 ADC。
如果該值在 memory 中開始,或者您想將原始值保留在寄存器中,請對目標進行異或零處理並使用 SUB/SBB。 SysV x86-32 ABI 在堆棧上傳遞參數並在 EDX:EAX 中返回 64 位整數。 這就是clang3.9.1 -m32 -O3
所做的,對於neg_value_from_mem
:
; optimal for data coming from memory: just subtract from zero
xor eax, eax
xor edx, edx
sub eax, dword ptr [esp + 4]
sbb edx, dword ptr [esp + 8]
如果您在寄存器中有值並且不需要就地結果,您可以使用NEG將寄存器設置為 0 - 本身,如果輸入不為零,則設置 CF。 即與 SUB 相同的方式。 請注意,異或歸零很便宜,並且不是延遲關鍵路徑的一部分,因此這絕對比 gcc 的 3 指令序列(如下)更好。
;; partially in-place: input in ecx:eax
xor edx, edx
neg eax ; eax = 0-eax, setting flags appropriately
sbb edx, ecx ;; result in edx:eax
即使對於就地情況,Clang 也會這樣做,即使這會花費額外的mov ecx,edx
。 這對於具有零延遲 mov reg,reg(Intel IvB+ 和 AMD Zen)的現代 CPU 的延遲是最佳的,但不適用於融合域 uops 的數量(前端吞吐量)或代碼大小。
gcc 的序列很有趣,但不是很明顯。 它為就地情況保存了一條指令 vs. clang,但否則情況會更糟。
; gcc's in-place sequence, only good for in-place use
neg eax
adc edx, 0
neg edx
; disadvantage: higher latency for the upper half than subtract-from-zero
; advantage: result in edx:eax with no extra registers used
不幸的是,gcc 和 MSVC 都總是使用它,即使 xor-zero + sub/sbb 會更好。
要更全面地了解編譯器的作用,請查看這些函數的輸出( 在 Godbolt 上)
#include <stdint.h>
int64_t neg_value_from_mem(int64_t a) {
return -a;
}
int64_t neg_value_in_regs(int64_t a) {
// The OR makes the compiler load+OR first
// but it can choose regs to set up for the negate
int64_t reg = a | 0x1111111111LL;
// clang chooses mov reg,mem / or reg,imm8 when possible,
// otherwise mov reg,imm32 / or reg,mem. Nice :)
return -reg;
}
int64_t foo();
int64_t neg_value_in_place(int64_t a) {
// foo's return value will be in edx:eax
return -foo();
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.