Жажда скорости Крис Касперски Хакер, номер #095, стр. 095-130-2 Кроме того, некоторые дампы выглядели абсолютно бессмысленными и даже мистическими. Как-то раз Доктор Ватсон заявил, что машинная команда XOR ECX,ECX возбудила исключение типа Access Violation по адресу C23BD2BAh, тогда как сам ECX равнялся 87h. Но ведь этого не может быть!!! Это же полная и абсолютная ерунда!!! Инструкция XOR ECX,ECX вообще не обращается к памяти!!! Но… протокол Доктора Ватсона есть протокол (читай: документ), и одним движением хвоста в корзину его не выбросишь… Озарение, как обычно, пришло после хорошей травы, тьфу, то есть во сне, точнее, не совсем во сне, а на границе сумеречной зоны, отделяющей один мир от другого, когда после 30 часов непрерывного «траханья» с Доктором Ватсоном ты спишь наяву, уткнувшись в очередной фрагмент кода, вызвавший сбой: 00000000: 33C9 XOR ECX, ECX ; (начальное значение ECX == 87h) 00000002: 33D2 XOR EDX, EDX 00000004: 3BC2 CMP EAX, EDX Ничего не напоминает?! Постой-постой! Но ведь… адрес, вызывавший исключение, содержит в себе байты инструкции CMP EAX,EDX и частично XOR EDX,EDX, а если записать опкоды этих команд и сложить их со значением регистра ECX, получится C23BD233h + 87h == C23BD2BAh, то есть тот самый, непонятно откуда взявшийся, адрес исключения (ну, это раньше он был непонятно откуда взявшийся, теперь же все стало ясно). Записав инструкцию XOR ECX,ECX в двоичном виде (00011 0011 1100 100) и изменив всего один бит, превращающий C9h в 89h, мы получим… мы получим вот что: 00000000: 338933D23BC2 XOR ECX,[ECX][0C23BD233] Оторвать мне хвост!!! Вот как, оказывается, в действительности выглядела машинная команда, возбудившая исключение и вызвавшая сбой. Сразу видно, что АЛУ тут совершенно не причем. Процессор функционировал, в общем-то, исправно. Весь вопрос в том, почему Доктор Ватсон показал не XOR ECX,[ECX][0C23BD233], а XOR ECX,ECX?! Да потому что искажение бита произошло в кэш-памяти первого уровня, а при составлении отчета Доктор Ватсон возвратил неискаженное содержимое кэш-памяти второго уровня!!! Откуда у меня такая уверенность, что все именно так и происходило? Так ведь процессор использует раздельную кэш-память первого уровня для кода и данных, поэтому прочитать истинное содержимое инструкции, вызвавшей сбой, Доктор Ватсон просто физически не в состоянии. Это можно установить только косвенным путем. Так значит, главный виновник — это кэш? Дальнейшие эксперименты показали, что все обстоит именно так. Причем сбои происходят в кэш-памяти обоих уровней, и вероятность их возникновения напрямую связана с интенсивностью кэш-промахов (то есть когда приложение обновляет большое количество кода/данных). С другой стороны, длительное хранение кода/данных без их модификации создает другую угрозу — угрозу «загнивания» байт, особенно часто случающуюся при некачественном питании. Изменить тактовую частоту кэш-модуля невозможно, но… если пораскинуть хвостом, можно найти довольно простое и элегантное решение. |