我正在学习MASM32,我正在学习各种轮班说明。
我能理解标准的移位指令,如SHL,SHR等,但我不清楚一些复杂的移位指令,如VPSLLVD,VPSRAVD等。
我的示例调试信息看起来像下面的Visual Studio(小端)。
我的示例项目是x86。
vpsllvd ymm5, ymm0, ymm1 ; logical shift left
; YMM0 = 000011C8000000E9-FFFFDC80FFFE9BB8-0000116400000001-000204E30003672C
; YMM1 = 000008AE00000384-0000005700000064-000000050000000A-00001E8100000BB8
; YMM5 = 0000000000000000-0000000000000000-00022C8000000400-0000000000000000
vpsravd ymm6, ymm0, ymm1 ; arimethic shift right
; YMM0 = 000011C8000000E9-FFFFDC80FFFE9BB8-0000116400000001-000204E30003672C
; YMM1 = 000008AE00000384-0000005700000064-000000050000000A-00001E8100000BB8
; YMM6 = 0000000000000000-FFFFFFFFFFFFFFFF-0000008B00000000-0000000000000000
我发现了移位算法,我试图理解这些移位指令的结果,但我还不能理解。
https://www.felixcloutier.com/x86/vpsllvw:vpsllvd:vpsllvq
VPSLLVD (VEX.256 version)
COUNT_0 := SRC2[31 : 0];
(* Repeat Each COUNT_i for the 2nd through 7th dwords of SRC2*)
COUNT_7 := SRC2[255 : 224];
IF COUNT_0 < 32 THEN
DEST[31:0] := ZeroExtend(SRC1[31:0] << COUNT_0);
ELSE
DEST[31:0] := 0;
(* Repeat shift operation for 2nd through 7th dwords *)
IF COUNT_7 < 32 THEN
DEST[255:224] := ZeroExtend(SRC1[255:224] << COUNT_7);
ELSE
DEST[255:224] := 0;
DEST[MAXVL-1:256] := 0;
https://www.felixcloutier.com/x86/vpsravw:vpsravd:vpsravq
VPSRAVD (VEX.256 version)
COUNT_0 := SRC2[31 : 0];
(* Repeat Each COUNT_i for the 2nd through 8th dwords of SRC2*)
COUNT_7 := SRC2[255 : 224];
DEST[31:0] := SignExtend(SRC1[31:0] >> COUNT_0);
(* Repeat shift operation for 2nd through 7th dwords *)
DEST[255:224] := SignExtend(SRC1[255:224] >> COUNT_7);
DEST[MAXVL-1:256] := 0;
你能解释一下这些移位指令是如何和我的例子调试信息一起工作的吗?
1条答案
按热度按时间vd8tlhqk1#
第二个操作数的每个双字都按照第三个操作数的相应双字指定的量移位,这与您已经熟悉的简单移位指令相同。
在第一个例子中,大多数移位量都大于32,因此这些双字的结果为零。让我们看看第三个块,它具有合理的值:
移位:
因此结果为
(00001164 << 5) (00000001 << A) = 00022C80 00000400
对于右移,第一个块中的输入为正,因此它们变为零,第二个块中的输入为负,因此由于算术移位被带符号,所以它们变为-1(
FFFFFFFF
)。