Вот пример смешных вещей, которые выясняются при тестировании процессорных инструкций. Есть в i386 команда POPAD. Когда мы находимся в 32-битном режиме, она выпихивает из стека значения восьми 32-битных регистров. Но значение ESP игнорирует, чтобы не нарушать стек. Это всё подробно описано и надёжно работает.
Но у команд i386 ещё бывают префиксы. Например префикс 0x67 меняет разрядность адресов в команде. В данном случае команда продолжает выпихивать 32-битные значения, но к стеку обращается по 16-битным адресам. Старшая половина ESP[31:16] игнорируется.
Вопрос: что происходит с этой старшей половиной ESP в результате выполнения команды POPAD с префиксом 0x67?
В документации вы прочитаете, что старшая половина регистра стека не изменяется. Это неправда. Как показывают тесты, биты ESP[31:16] получают значение из стека, как и прочие регистры. Был стек ESP=0x00005E90, стал 0x5A045EB0. Неожиданность! Как говорится, это нельзя объяснить, можно только запомнить. 😀
Но у команд i386 ещё бывают префиксы. Например префикс 0x67 меняет разрядность адресов в команде. В данном случае команда продолжает выпихивать 32-битные значения, но к стеку обращается по 16-битным адресам. Старшая половина ESP[31:16] игнорируется.
Вопрос: что происходит с этой старшей половиной ESP в результате выполнения команды POPAD с префиксом 0x67?
В документации вы прочитаете, что старшая половина регистра стека не изменяется. Это неправда. Как показывают тесты, биты ESP[31:16] получают значение из стека, как и прочие регистры. Был стек ESP=0x00005E90, стал 0x5A045EB0. Неожиданность! Как говорится, это нельзя объяснить, можно только запомнить. 😀
