четверг, 31 января 2008 г.

Баг процессора?

Странную штуку обнаружил. Судя по всему команда pop cs должна быть интерпретирована как двухбайтовая, хотя код имеет однобайтовый.

000 sreg2 111, при sreg2 равном 01, что означает cs, даст код 0x0f, с которого начинаются все двухбайтовые команды.

Хотя с другой стороны эта же команда может быть закодирована через 0x0f 0x89, и скорее всего любой вменяемый ассемблер должен так и поступить. Проверять лень.

Я конечно вполне понимаю всю практическую бесполезность данной команды, но не смотря на это в мануале она описана. Ее теоретически можно даже использовать например при переходе в защищенный режим делать не

    jmp KERNEL_CODE_SELECTOR:label
label:

а
    push KERNEL_CODE_SELECTOR
    pop cs

При условии, что eip не изменяется.

PS: В принципе возникноверие этой нестыковки понятно. На 286 было мало команд и мало регистров, двух бит хватало на сегментный регистр, но в 386 появились дополнительные сегментные регистры fs и gs, кроме того 256 кодов стало не хватать, а других свободных кодов не было, и видимо было принято решение использовать для расширенных инструкций код 0x0f, посколько никто никогда не использует короткую форму pop cs. Да и длинная по большому счету не нужна никому.

PPS: B IA32 Software Developer Manual кстати, в описании команды pop, написано
The POP instruction cannot pop a value into the CS register. To load the CS register from the stack, use the RET instruction.
Но ведь закодировать то можно. Прям загадка какая-то. :)

1 коммент.:

Анонимный комментирует...

Слова "The POP instruction cannot pop a value into the CS register. To load the CS register from the stack, use the RET instruction." значит, что POP CS в любом формате не поддерживается. Соответственно. POP CS в виде 0x0f не является инструкцией POP. Закодировать можно и доступ ко всем CR* и DR*.