3

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 でなければならないということですか?

4

1 に答える 1

2

LIG は、L ビットが無視されるという意味ではないようです。マニュアルのその部分が間違っています。実際には、これは.LZorの同義語で.128あり、L が 0 でなければならないことを意味します。

Intel の insn ref マニュアル (セクション 3.1.1.2 ( x86 マニュアルの第 2 巻の命令概要表 (VEX 接頭辞付きの命令)の Opcode 列)) は、観察された動作と矛盾しています。

オペコード列に VEX.LIG が存在する場合: VEX.L 値は無視されます。これは通常、VEX でエンコードされたスカラー SIMD 浮動小数点命令に適用されます。

ただし、同じマニュアル内の他のドキュメントとも矛盾しています。Intel のマニュアルには時折間違いがあります。:( Intel のフォーラムでバグを報告できると思います。


おそらく Intel はビットを無視することについて考えを変え、スカラー オペコードの L=1 エンコーディングを予約しておくことに決めましたが、VEX.LIG が insn-encoding セクションで何を意味するかについてドキュメントを更新するのを忘れていました。

彼らは、おそらくハードウェア設計のすべての詳細が確定する前に、正式になる前に insn set リファレンス マニュアルの将来の拡張アップデートを公開します。(現在の将来の拡張の補足 pdf では、AVX512 命令 (KNL にあります) と、まだ公式マニュアルにない、または市販のシリコン AFAIK で利用可能ないくつかの他の拡張について説明しています。) (Intel のドキュメント ページへのリンク、およびタグ wiki 内の他の多くのもの)。


Intel の insn ref マニュアルから、Fig2-9 VEX ビット フィールド:

L: ベクトルの長さ

  1. スカラーまたは 128 ビットのベクトル
  2. 256 ビットのベクトル

セクション 2.3.6.2 で同じことを説明しています。


一部の BMI1/2 命令は VEX エンコーディングを使用し、これも L=0 であることに注意してください。.Lz: VEX.NDS.LZ.0F38.W0 F2 /ris で示しているようですANDN r32a, r32b, r/m32

于 2016-09-05T14:23:00.627 に答える