I have been doing some work and noticed that in decode.c in handle_prefix there's some code that confuses me. The comments say (correctly) that a REX prefix must be last. The rules say legacy prefixes, then REX if needed, the the opcode. But the code really does not enforce this. For example, I ran this with udcli (added some comments):
41 63 c2 The rex prefix is 41 - looks OK
000000000000000b 4163c2 movsxd rax, r10d
2e 41 63 c2 OK here is a CS segment legacy prefix which is ignored, then the REX prefix - looks OK
000000000000000e 2e4163c2 movsxd rax, r10d
41 2e 63 c2 Now let's have the REX and then the CS override. Should this not be illegal?
0000000000000012 412e63c2 movsxd rax, edx
The tail end of decode_prefix in decode.c has this:
I have been doing some work and noticed that in decode.c in handle_prefix there's some code that confuses me. The comments say (correctly) that a REX prefix must be last. The rules say legacy prefixes, then REX if needed, the the opcode. But the code really does not enforce this. For example, I ran this with udcli (added some comments):
41 63 c2 The rex prefix is 41 - looks OK 000000000000000b 4163c2 movsxd rax, r10d
2e 41 63 c2 OK here is a CS segment legacy prefix which is ignored, then the REX prefix - looks OK 000000000000000e 2e4163c2 movsxd rax, r10d
41 2e 63 c2 Now let's have the REX and then the CS override. Should this not be illegal? 0000000000000012 412e63c2 movsxd rax, edx
The tail end of decode_prefix in decode.c has this:
done = (u->dis_mode == 64 && (curr & 0xF0) == 0x40) ? 0 : 1;
But what this says to me is "if you see a REX prefix in 64 bit mode, you are NOT done." Then later it assigns the variable "last" over to the prefix:
So I think the comment is right but the behavior is not exactly correct.
Thoughts?