[英]How can I pass an immediate value to shr in assembly in Intel syntax?
根據該引用和該引用 , shr
指令支持通過CL
寄存器和立即值移位1
。 但是,我似乎無法立即獲得工作價值; 當我有這個代碼時:
#include <stdint.h>
int main() {
uint64_t v = 15;
asm ("shr %[v], $0x04\t\n"
: [v] "+r" (v)
:
: "cc"
);
return v;
}
我收到此錯誤消息:
$ gcc -masm=intel foo.c foo.c: Assembler messages: foo.c:5: Error: operand size mismatch for `shr'
如何將立即值傳遞給shr
(不將其加載到CL
,我關心它,因為我正在針對寄存器壓力瓶頸進行優化)。
您正在使用具有Intel匯編語法的指南。 GNU程序集(GAS)使用AT&T語法,它具有操作數的逆序。 改變他們的順序似乎做得很好:
uint64_t v = 0xffff;
asm ("shr $0x04, %[v]\n"
: [v] "+r" (v)
:
: "cc"
);
printf("%llx", v); // 0xfff
(您也可以用shrq
替換shr
以顯式使用64位操作數)
如果您仍然希望像使用-masm=intel
一樣使用Intel語法,則必須從立即值中刪除美元符號:
asm ("shr %[v], 4\n"
...)
如果你使用-masm=intel
,它會激活.intel_syntax noprefix
。 Immediates不再采用$
前綴。 (但對於地址,您需要OFFSET symbol
)。 無論如何,不要使用$
。
顯然,如果你只是想要一個班次,你應該用C代替內聯asm https://gcc.gnu.org/wiki/DontUseInlineAsm 。 (您可以屏蔽移位計數以避免UB的移位計數太高,例如旋轉: C ++中循環移位(旋轉)操作的最佳實踐 )
但是如果你想將它用作需要內聯asm的東西的一部分,那么你可以這樣做,以允許旋轉計數為C中的變量(在cl
)或常量(立即)。我使用了"cJ"
允許0-63
立即數操作數( J
)的約束 ,或rcx/ecx/cx/cl
( c
約束)中的寄存器操作數。 (特別是在cl
,因為我轉向(uint8_t)
。
另外,我使用b
修飾符來覆蓋大小,以防你想要在轉換之前使用整個rcx
作為其他東西的命名輸入。 (參見gcc文檔中的6.45.2.8 x86操作數修飾符 )。
有關某些指南,另請參閱inline-assembly標記wiki。
我使用https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html#Multiple-assembler-dialects-in-asm-templates來使用AT&T或Intel語法模式正確編譯和匯編。
在Godbolt編譯器資源管理器中 ,您可以看到這與gcc一起使用,但是對於inline-asm,clang與-masm=intel
無法正常工作。 它仍然替換為%rdi
而不是rdi
並且無法組裝。
static inline uint64_t shr (uint64_t v, unsigned c)
{
// %b[c] is cl even if %[c] is ecx or whatever.
asm ("shr {%b[c],%[v] | %[v],%b[c]}"
: [v] "+r" (v)
: [c] "cJ" ((uint8_t)c)); // the cast gets this to use cl
return v;
}
uint64_t shr_variable(uint64_t v, int c) {
return shr(v, c);
}
mov rax, rdi
mov ecx, esi
shr rax,cl
ret
uint64_t shr_const(uint64_t v) {
return shr(v, 13);
}
mov rax, rdi
shr rax,13
ret
將其與純C進行比較,使用-march=haswell
:
// can use SHRX with BMI2 available. And can optimize much better
uint64_t shr_variable_purec(uint64_t v, unsigned c) {
//c &= 63; // optional, compiles to zero instructions on x86 because shr and shrx already do this.
return v >> c;
}
shrx rax, rdi, rsi
ret
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.