I'm currently in the process of developing a disassembler for the x86_x64 CISC. I have 2 questions regarding prefix instruction decoding:
For the following stream:
\x9b\x9b\xd9\x30
GCC
andobjdump
outputsfstenv [eax]
So they're first reading all prefixes (no more than 15) and then proceed to check the correct instruction using the last prefix read
\x9b
with\xd9
to make it afstenv
instruction.Capstone
on the other hand outputswait wait fnstenv dword ptr [eax]
Now, obviously capstone in on the wrong that it puts 2
wait
instructions and not just 1. But should it putwait
instructions at all orGCC
andobjdump
is on the right here for consuming all the extra\x9b
prefixes for thefstenv
instruction?For the following stream:
\xf2\x66\x0f\x12\x00
GCC
andobjdump
outputdata16 movddup xmm0,QWORD PTR [eax]
So they're arranging the prefixes in a specific order so
\x66
is interpreted before\xf2
thus, and so they're still using the last prefix read\xf2
to determine the instructionmovddup
. So is they're right here for using this arrange logic of the prefixes or are they wrong?Capstone
on the other hand outputsmovlpd xmm0, qword ptr [eax]
So they're not arranging the prefixes in any order and they're just taking the last prefix read
\x66
to determine the instructionmovlpd
which looks more logical in this case than whatGCC
andobjdump
were doing.
How is the cpu actually interpreting these streams?
fstenv
does not really exist. The instruction set reference says: "The assembler issues two instructions for the FSTENV instruction (an FWAIT instruction followed by an FNSTENV instruction), and the processor executes each of these instructions separately." Capstone is technically correct. – Denialwait
is not a prefix. – DenialF2
prefix to that instruction so it's hard to argue which version is correct. My cpu (amd ryzen 1700) seems to think objdump is right, it is executed asmovddup
. TBH, I expected it to be amovlpd
... – Denialmovddup
. – Denial