我真的很困惑,请帮忙...
我已经从intel订购了一堆书,软件开发人员手册,并且在书中给了我所有这些操作码,例如“ VEX.128 ...”或“ 0F 5B”
这些书说诸如“这可以与XMM寄存器一起使用”之类的东西,但是没有一本书谈论如何将XMM单词转换为十六进制?
我想做的事情就像在不使用汇编程序的情况下以纯十六进制形式写问好世界!请帮忙!我希望这对我来说是汇编语言和十六进制代码领域的新手
答案 0 :(得分:3)
单词XMM不会转换为十六进制。指令使用XMM寄存器是操作码和前缀的属性。寄存器操作数的索引主要由ModRM字节编码,在前缀中稍微增加一点,对于GPR上的某些操作,寄存器名称被编码在操作码字节中。
除了复杂性,这里还有一个简单的VEX前缀示例vpaddb xmm1, xmm4, xmm6
。它在手册中的条目(在paddb
引理下)表示将其编码为:VEX.NDS.128.66.0F.WIG FC /r
VEX.NDS.128.66.0F.WIG
用于VEX前缀。 NDS表示vvvv字段对源寄存器进行编码。 128
表示不设置L位,这使寄存器使用 X MM版本,否则它们将是 Y MM版本(如您所见)这种区别是由VEX前缀中的单个位编码的,而不是通过用十六进制精确地写单词“ XMM”来编码的。66
表示pp字段的设置,该设置对应于传统编码中的强制前缀=01。WIG= W忽略,这里并不重要。
无论如何,它可以是2字节的VEX前缀(无特殊操作码映射,寄存器编号低),因此以C5
开头,然后合并字段~R|~vvvv|L|pp
(其中|
是级联)。 〜vvvv是vvvv的补码,vvvv = 0100(xmm 4 )。 R字段是ModRM字节的reg字段的扩展,xmm1
的索引小于8,因此R字段为0,因此〜R为1。结合起来,第二个前缀字节为{{1} }。
操作码字节为1|1011|0|01 = D9
,在这里没有任何有趣的事情。
FC
意味着将其余操作数编码为ModRM(+ SIB),因此这里使用mod = 11(两个寄存器,没有内存操作数),rm = 110(xmm 6 ),reg = 001(xmm 1 ),所以/r
因此,总共11001110 = CE
变为vpaddb xmm1,xmm4,xmm6
。
您可以在ISDM的附录B“指令格式和编码”中找到此信息(以及一些略过的细节)。