英特尔指令集参考为我们提供了添加指令:
0xC4, 0xE1, 0x7B, 0x58, 0xC0
我们可以看到L位被忽略(可以是0或1)。
机器码添加xmm0,xmm0,xmm0 :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));
}
我们来测试一下:
Thisworkbook.Sheets("SheetName").Cells(1, Columns.Count).End(xlToLeft).Column
很好,视觉工作室反汇编程序也会识别该指令。
然而,当我将 L位更改为1 (0x7B替换为0x7F)时,反汇编程序无法识别该指令并生成无效指令异常。这是否意味着尽管有英特尔手册,L位必须始终为0?
答案 0 :(得分:2)
看起来LIG并不意味着L位被忽略; 手册的那部分内容错误。在实践中,它实际上是.LZ
或.128
的同义词,并且意味着L必须为0.
英特尔的insn参考手册(x86第2卷第3.1.1.2节(指令汇总表中的操作码列(带VEX前缀的说明))手册)与观察到的行为相矛盾:
如果操作码列中存在VEX.LIG:VEX.L值为 忽略。这通常适用于VEX编码的标量SIMD 浮点指令。
但是,它也与同一手册中的其他文档相矛盾。英特尔的手册偶尔会出现错误。 :(我认为你可以报告英特尔论坛上的错误。
据推测,英特尔改变主意忽略该位,并决定保留标量操作码保留的L = 1编码,但忘记更新文档以了解VEX.LIG在insn编码部分的含义。
他们在insn set参考手册成为正式之前发布未来扩展更新,可能在硬件设计的每个细节最终确定之前。 (目前的future-extensions补充pdf描述了AVX512指令(在KNL中找到),以及一些其他扩展,这些扩展还没有在官方手册中提供,或者可以在任何商用硅AFAIK中获得。)(链接到Intel&# 39; s文档页面,以及x86标签wiki中的大量其他内容。
来自英特尔的insn参考手册,图2-9 VEX位字段:
L:矢量长度
- 标量或128位向量
- 256位向量
醇>
第2.3.6.2节解释了同样的事情。
请注意,某些BMI1 / 2指令使用VEX编码,L = 0。看起来他们用.Lz
表示它:VEX.NDS.LZ.0F38.W0 F2 /r
是
ANDN r32a, r32b, r/m32
。