Intel 命令セット リファレンスは、addsd命令を提供します。
VEX.NDS.LIG.F2.0F.WIG 58 /r
VADDSD xmm1, xmm2, xmm3/m64
ご覧のとおり、L ビットは無視されます (0 または 1 のいずれか)。
addsd xmm0, xmm0, xmm0のマシンコード:0xC4, 0xE1, 0x7B, 0x58, 0xC0
C4 - indicates 3-byte VEX prefix
E1 - R = 1; X = 1; B = 1; m-mmmm = 1 (implied 0F escape)
7B - W = 0; vvvv = 1111 (xmm0); L = 0; pp = 11 (implied F2 prefix)
58 - opcode byte
C0 - mod-rm byte
テストしましょう:
void exec(Byte* code, int size)
{
Byte* buf = (Byte*)VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(buf, code, size);
buf[size] = 0xC3;
((void (*)())buf)();
VirtualFree(buf, 4096, MEM_DECOMMIT);
}
void f()
{
Byte code[] = { 0xC4, 0xE1, 0x7B, 0x58, 0xC0 };
exec(code, sizeof(code));
}
また、Visual Studio の逆アセンブラーも命令を認識します。
しかし、L ビットを 1に変更すると(0x7B は 0x7F に置き換えられます)、逆アセンブラは命令を認識せず、無効命令例外が生成されます。Intel のマニュアルにもかかわらず、L ビットは常に 0 でなければならないということですか?