我在記憶體中的某個地址有一個浮點值,我想使用該地址將 XMM 暫存器設定為該值。我正在使用asmjit。
此代碼適用于 32 位構建并將 XMM 暫存器v設定為正確的值*f:
using namespace asmjit;
using namespace x86;
void setXmmVarViaAddressLocation(X86Compiler& cc, X86Xmm& v, const float* f)
{
cc.movq(v, X86Mem(reinterpret_cast<std::uintptr_t>(f)));
}
但是,當我以 64 位編譯時,嘗試使用該暫存器時會出現段錯誤。這是為什么?
(是的,我在集會方面不是很強大……請客氣……我已經在這個問題上呆了一天了……)
uj5u.com熱心網友回復:
最簡單的解決方案是避免ptr(). 原因是 x86/x86_64 需要 32 位位移,這對于任意用戶地址并不總是可能的 - 位移是通過使用當前指令指標和目標地址計算的 - 如果差異在有符號的 32 位整數之外指令不可編碼(這是架構約束)。
示例代碼:
using namespace asmjit;
void setXmmVarViaAddressLocation(x86::Compiler& cc, x86::Xmm& v, const float* f)
{
x86::Gp tmpPtr = cc.newIntPtr("tmpPtr");
cc.mov(tmpPtr, reinterpret_cast<std::uintptr_t>(f);
cc.movq(v, x86::ptr(tmpPtr));
}
如果要針對 32 位模式優化此代碼,但沒有問題,則必須先檢查目標架構,例如:
using namespace asmjit;
void setXmmVarViaAddressLocation(x86::Compiler& cc, x86::Xmm& v, const float* f)
{
// Ideally, abstract this out so the code doesn't repeat.
x86::Mem m;
if (cc.is32Bit() || reinterpret_cast<std::uintptr_t>(f) <= 0xFFFFFFFFu) {
m = x86::ptr(reinterpret_cast<std::uintptr_t>(f));
}
else {
x86::Gp tmpPtr = cc.newIntPtr("tmpPtr");
cc.mov(tmpPtr, reinterpret_cast<std::uintptr_t>(f);
m = x86::ptr(tmpPtr);
}
// Do the move, now the content of `m` depends on target arch.
cc.movq(v, x86::ptr(tmpPtr));
}
這樣你就可以在 32 位模式下保存一個暫存器,這總是很寶貴的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/369169.html
上一篇:為什么這個PowerPC指令序列似乎同時設定了cr0和cr1?
下一篇:如何制作可啟動軟盤映像?
