в общем, на входе стоит "декодер длины команд". из него получаются макро-операции, которые идут в очередь макроопераций. посмотрев какое пенальти за много rex-префиксов, я сделал вывод, что аппаратно они реализованы так, что даже не декодируются, а лишь ставят флажки для следующей инструкции. т.к. проц не чувствителен к их числу по части скорости.
обычные декодеры работают уже после декодеров длины, и по командам из очереди макроопераций, когда уже понятно какие байты жрать. и только для простых команд. но это не наш случай.
также не наш случай - кэш микроопераций. там 18 команд на 32байта, то есть описание причин сбоя неверное.
сложные команды которые являются номером в таблице + набором полей imm32,reg1,reg2,reg3,размер. в таблице лежит адрес кода в прошивке который будет выполнен. в микрокоде наверняка есть специальные псевдорегистры для указания временных регистров, или подстановки reg1,reg2,...imm. почему таблица? потому что прошивка может меняться и адреса в ней плавают. префиксы также влияют на адрес в таблице, например выставляют какой-то бит в опкоде. rex префикс ну просто явно выставляет какие-то биты и ничего больше не делает. ну в общем так бы я делал.
дальше начинает работать код из MS-ROM, который смотрит на то какой был опкод, какие были регистры и т.д. и тут интересный момент: rex.w + movsb = movsq, допустимая команда. а вот rex.r нет. пропуски ветвлений и ветвления мимо кассы могут указывать что команды после сбойной movsb просто не выполняются. походу добавленный код FSRM улетает куда-то по левому указателю или может быть даже делает это намеренно.
кто нибудь проверьте в коде теста на багу следующие варианты правок в однопоточном варианте. в icebreak.asm вот этот код:
rep
rex
rex r
movsb
на такие варианты:
rep + rex r + movsb
rep + rex b + movsb
rep + rex x + movsb
rep + rex + rex w + movsb
rep + rex + rex b + movsb
rep + rex + rex x + movsb
и еще те же варианты + в начале mov rdx, rsp, заполнить [rsp-64, rsp-8] нулями + сразу после багокоманды команда call $0 (0xe0 0 0 0 0 20 раз) и сохранить данные из стека [rdx-64, rdx-8]. и потом mov rsp, rdx. тогда можно будет точнее сказать что там происходит
алсо оказывается с множественными rex-префиксами кто-то уже натыкался на крахи еще в 2016м году
https://keyboardsmoke.wordpress.com/2016/09/26/multiple-rex-.../
I have run into crashes in some circumstances with certain (unknown) combinations of REX bytes, but the examples here seem to work, and I can’t see any clear difference in the state of the program.