Вот пример смешных вещей, которые выясняются при тестировании процессорных инструкций. Есть в 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. Неожиданность! Как говорится, это нельзя объяснить, можно только запомнить. 😀

no subject
Date: 2026-02-28 02:27 (UTC)no subject
Date: 2026-02-28 05:12 (UTC)no subject
Date: 2026-02-28 07:30 (UTC)no subject
Date: 2026-02-28 12:16 (UTC)no subject
Date: 2026-03-01 05:35 (UTC)no subject
Date: 2026-03-01 07:32 (UTC)Проверил код в DOSBox - аномалий нет, а префикс AS ни на что не влияет.
Интересно каким кодом вы обнаружили аномалию?
no subject
Date: 2026-03-01 07:49 (UTC)==== Test #0 (1254 bytes) ==== Name: "popad" Initial CPU State: Registers: cr0 = 7FFEFFF0 (2147418096) cr3 = 00000000 (0) eax = 9192DBB2 (2442320818) ebx = 99C59D4B (2579864907) ecx = 4A3B1694 (1245386388) edx = 5E456BE5 (1581607909) esi = FEC2D97F (4274182527) edi = 176802DB (392692443) ebp = 7839DC30 (2017057840) esp = 00005E90 (24208) cs = 0000F2AA (62122) ds = 0000FBD5 (64469) es = 00004000 (16384) fs = 0000CEDD (52957) gs = 0000005F (95) ss = 000077BF (30655) eip = 0000A488 (42120) eflags = FFFC0C86 (4294708358) dr6 = FFFF0FF0 (4294905840) dr7 = 00000000 (0) RAM entries: 46 FCF28 = 66 (102) FCF29 = 61 (97) FCF2A = F4 (244) FCF2B = 82 (130) FCF2C = 0A (10) FCF2D = BE (190) FCF2E = 51 (81) FCF2F = 9C (156) FCF30 = 37 (55) FCF31 = 02 (2) 7DA80 = EA (234) 7DA81 = 49 (73) 7DA82 = 91 (145) 7DA83 = FA (250) 7DA84 = 81 (129) 7DA85 = E1 (225) 7DA86 = C6 (198) 7DA87 = A5 (165) 7DA88 = B6 (182) 7DA89 = B7 (183) 7DA8A = 86 (134) 7DA8B = 02 (2) 7DA8C = 18 (24) 7DA8D = 6B (107) 7DA8E = 04 (4) 7DA8F = 5A (90) 7DA90 = E4 (228) 7DA91 = 22 (34) 7DA92 = BF (191) 7DA93 = A3 (163) 7DA94 = BE (190) 7DA95 = BB (187) 7DA96 = 88 (136) 7DA97 = 56 (86) 7DA98 = 41 (65) 7DA99 = E0 (224) 7DA9A = 10 (16) 7DA9B = 37 (55) 7DA9C = F3 (243) 7DA9D = EB (235) 7DA9E = B6 (182) 7DA9F = 7C (124) FCF32 = F9 (249) FCF33 = 56 (86) FCF34 = 5F (95) FCF35 = B5 (181) Final CPU State: Registers: cr0 = 7FFEFFF0 (2147418096) cr3 = 00000000 (0) eax = 7CB6EBF3 (2092362739) ebx = A3BF22E4 (2747212516) ecx = 3710E041 (923852865) edx = 5688BBBE (1451801534) esi = A5C6E181 (2781274497) edi = FA9149EA (4203825642) ebp = 0286B7B6 (42383286) esp = 5A045EB0 (1510235824) cs = 0000F2AA (62122) ds = 0000FBD5 (64469) es = 00004000 (16384) fs = 0000CEDD (52957) gs = 0000005F (95) ss = 000077BF (30655) eip = 0000A48B (42123) eflags = FFFC0C86 (4294708358) dr6 = FFFF0FF0 (4294905840) dr7 = 00000000 (0)Это первый из файла https://github.com/SingleStepTests/80386/blob/main/v1_ex_real_mode/6661.MOO.gz.
no subject
Date: 2026-03-01 09:08 (UTC)И там упоминается, что используют LOADALL, который с 486 отменили совсем. У меня где-то валяется старая платка с 386, жалко выбрасывать - в 1993 привезли для меня из США по спецзаказу! Может попробую с ней.
no subject
Date: 2026-03-01 09:31 (UTC)Наверное можно сконвертировать для запуска под MSDOS, только адреса памяти заменить, чтобы попадало в 640 кбайт.
no subject
Date: 2026-03-01 10:28 (UTC)no subject
Date: 2026-03-01 12:59 (UTC)no subject
Date: 2026-02-28 13:37 (UTC)no subject
Date: 2026-02-28 19:07 (UTC)no subject
Date: 2026-03-03 13:08 (UTC)Ну и запутали вы с префиксом AS... ;)
Сделал ещё код для загрузочного сектора, он поддерживает 32-битную адресацию в 16-битном режиме, но как оказалось это для выявления аномалии было лишним.
На Целероне и почти современной Аэмдешке всё правильно - аномалия не проявляется.
Трудно представить, что на этом баге кто-то мог спотыкнуться. Старшие разряды ESP всё равно не используются в ДОС. Это не тот кошмар, как с известным POPAD-багом, когда ломается всё. Похоже тот, кто ваял POPAD, или спешил, или ещё что-то.
no subject
Date: 2026-03-04 08:29 (UTC)Ага, таки не врут тесты! 😀 За что я их и ценю. Дают возможность узнать много нового про железо.
> Интересно его хоть где-то задокументировали?
Этот вопрос тянет на серьёзное историческое исследование. Раздобыть историю всех изменений в генеалогическом древе процессоров x86. 😀
> И, интересно, а как вы получили данные прогонов с реального железа?
Не я получил, это Daniel Balsom, автор известного симулятора MartyPC. Он умелый чувак.
> Эти му-тесты вроде сделаны для эмуляторов и не очень хороши для штатных ПК.
> Ещё у этих му-тестов непонятно в каком они режиме: 16- или 32-битном. :(
Ну, для чего мы приспосабливаем эти тесты уже наша проблема. Сами по себе они исторический артефакт. Дают аутентичный слепок с реального хардвера.
Там в README всё объясняется: в папке v1_ex_real_mode (а она пока единственная) лежат тесты реального режима. Что означает 16-битный режим процессора i8086.
> Ну и запутали вы с префиксом AS... ;)
Я наоборот, в том посте старался абстрагироваться и говорить про 32-битный режим. Не вдаваясь в подробности особенностей MOO тестов. Уж как вышло, извините. 😀
> На Целероне и почти современной Аэмдешке всё правильно - аномалия не проявляется.
Таки исправили позднее, значит.