Assembly 是否可以构造一个跳转到SIMD寄存器的x86_64操作码?
今天早上我有一个有趣的想法。我想知道是否有可能构造一个无条件跳转到存储在SIMD寄存器(如XMM0)中的地址。显然,它不应该这样做,而且我从未见过编译器这样做,但我想知道是否有可能组合一个操作码来实现它 现在我的意思不是说在SIMD寄存器中做一些算术运算,将它移到通用寄存器,然后执行sayAssembly 是否可以构造一个跳转到SIMD寄存器的x86_64操作码?,assembly,x86-64,simd,opcode,Assembly,X86 64,Simd,Opcode,今天早上我有一个有趣的想法。我想知道是否有可能构造一个无条件跳转到存储在SIMD寄存器(如XMM0)中的地址。显然,它不应该这样做,而且我从未见过编译器这样做,但我想知道是否有可能组合一个操作码来实现它 现在我的意思不是说在SIMD寄存器中做一些算术运算,将它移到通用寄存器,然后执行say JMP EAX 我想做的是,弄清楚是否有一个可接受的X86_64操作码可以执行类似的操作 JMP XMM0 当然,不知何故,你只需要抓住登记册的前半部分。这很可能是不可能的,但我很好奇这是不是真的,或者为
JMP EAX
我想做的是,弄清楚是否有一个可接受的X86_64操作码可以执行类似的操作
JMP XMM0
当然,不知何故,你只需要抓住登记册的前半部分。这很可能是不可能的,但我很好奇这是不是真的,或者为什么不能做到 这样的指令并不存在。唯一的
jmp
指令是:
EB cb JMP rel8 jump short
E9 cw/cd JMP rel16/32 jump near
FF /4 JMP r/m16/32/64 jump near indirect
EA cd/cp JMP ptr16:16/32 jump far
FF /5 JMP m16:16/32 jump far indirect
REX.W FF /5 JMP m16:64 jump far indirect
这些指令要么跳转到立即数、通用寄存器或内存操作数中给定的地址。不能使用SSE寄存器
有许多其他指令可用于跳转,例如
ret
,但它们都不支持跳转到SSE寄存器。这样的指令不存在。唯一的jmp
指令是:
EB cb JMP rel8 jump short
E9 cw/cd JMP rel16/32 jump near
FF /4 JMP r/m16/32/64 jump near indirect
EA cd/cp JMP ptr16:16/32 jump far
FF /5 JMP m16:16/32 jump far indirect
REX.W FF /5 JMP m16:64 jump far indirect
这些指令要么跳转到立即数、通用寄存器或内存操作数中给定的地址。不能使用SSE寄存器
还有许多其他指令可用于跳转,例如
ret
,但是它们都不支持跳转到SSE寄存器。虽然它确实要经过内存,从技术上讲它是3条指令,但你可以说48 8D 64 24 F8 66 0F D6 04 24 C3
实际上是一个jmp xmm0
操作码。
当然只是
lea rsp, [rsp-8]
movq [rsp], xmm0
ret
这可能属于您的排除范围,但它不会破坏任何寄存器或标志,所以如果这是您的原因,这应该会起作用
如果您有可用的红色区域,您可以这样做
movq [rsp-8], xmm0
jmp [rsp-8]
相反。虽然它确实要经过内存,从技术上讲它是3条指令,但您可以认为
48 8D 64 24 F8 66 0F D6 04 24 C3
实际上是一个jmp xmm0
操作码。
当然只是
lea rsp, [rsp-8]
movq [rsp], xmm0
ret
这可能属于您的排除范围,但它不会破坏任何寄存器或标志,所以如果这是您的原因,这应该会起作用
如果您有可用的红色区域,您可以这样做
movq [rsp-8], xmm0
jmp [rsp-8]
相反。不,你不能。你甚至不能将这些寄存器推到堆栈中,所以你的最佳选择似乎是将其移动到EAX,然后移动到JMP EAX。我不知道是谁对此投了反对票,它符合格式要求。。。另外,问题是编码中可以构造什么,而不是基于x86文档可以构造什么。你甚至不能将这些寄存器推到堆栈中,所以你的最佳选择似乎是将其移动到EAX,然后移动到JMP EAX。我不知道是谁对此投了反对票,它符合格式要求。。。还有一个问题是编码中可以构造什么,而不是基于x86文档可以构造什么。我很好奇,你能举个例子说明EAX的跳远间接吗?我不知道你的符号“FF/5”或“REX.W FF/5”是什么意思。@baordog
FF/5
表示“操作码FF
然后是一个modr/m字节,第二个操作数的值为5”。这5是一个扩展操作码,作为指令的第二个参数编码,通常只包含一个参数。例如,JMP FAR[EAX]
编码为ff 28
,其中28(八进制,050)是对操作数[EAX]
(由八进制0x0表示)和扩展操作码5进行编码的modr/m字节。REX.W表示“打开W位的REX前缀”。REX前缀为40到4F,W位的值为8,因此REX.W单独为48。W位将操作数大小从32位更改为64位。例如,跳转到64位地址的指令jmp far[rax]
被编码为48 ff 28
。我很好奇,你能给我举一个例子说明EAX的跳转far间接吗?我不知道你的符号“FF/5”或“REX.W FF/5”是什么意思。@baordogFF/5
表示“操作码FF
然后是一个modr/m字节,第二个操作数的值为5”。这5是一个扩展操作码,作为指令的第二个参数编码,通常只包含一个参数。例如,JMP FAR[EAX]
编码为ff 28
,其中28(八进制,050)是对操作数[EAX]
(由八进制0x0表示)和扩展操作码5进行编码的modr/m字节。REX.W表示“打开W位的REX前缀”。REX前缀为40到4F,W位的值为8,因此REX.W单独为48。W位将操作数大小从32位更改为64位。例如,跳转到64位地址的指令jmp far[rax]
编码为48 ff 28
。请记住,第一种方法将中断调用
/ret
预测器,可能会在后续ret
指令上发生预测失误,可能还会发生几次。请记住,第一种方法将中断调用/ret
预测,可能会在后续ret
指令上发生预测失误,可能还会发生几次预测失误。