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\x30GCCandobjdumpoutputsfstenv [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
\x9bwith\xd9to make it afstenvinstruction.Capstoneon the other hand outputswait wait fnstenv dword ptr [eax]Now, obviously capstone in on the wrong that it puts 2
waitinstructions and not just 1. But should it putwaitinstructions at all orGCCandobjdumpis on the right here for consuming all the extra\x9bprefixes for thefstenvinstruction?For the following stream:
\xf2\x66\x0f\x12\x00GCCandobjdumpoutputdata16 movddup xmm0,QWORD PTR [eax]So they're arranging the prefixes in a specific order so
\x66is interpreted before\xf2thus, and so they're still using the last prefix read\xf2to determine the instructionmovddup. So is they're right here for using this arrange logic of the prefixes or are they wrong?Capstoneon 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
\x66to determine the instructionmovlpdwhich looks more logical in this case than whatGCCandobjdumpwere doing.
How is the cpu actually interpreting these streams?
fstenvdoes 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.waitis not a prefix.F2prefix 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...