Здравствуйте, ononim, Вы писали:
O>Почему вас смущает что InternetGetConnectedState сохраняет внутри себя MMX регистры перед тем как вызывать какие то свои внутренние потроха (которые юзают SSE)?
Потому что я знаю, что делают команды SSE2, для которых задействованы регистры XMM. И на кой ляд в подпрограмме возвращающей статус соединения в интернете, нужны команды (и регистры) обрабатывающие по два double за раз, не понимаю.
O>Действительно не понимаем. Я имел ввиду что есть два рода исключений. Первое — исключения уровня логики приложения. Второе — исключения уровня защиты ОС от неверного функционирования программы. Ваше underflow exception — относится к первым. Такие не могут привести к вызову обработчика исключений на невыровненном стеке, поскольку места из которых они могут вылететь известны компилятору и он генерит код таким образом, чтобы исключения логики генерились на корректном стеке.
Компилятор никаких исключений не генерирует. По определению исключение может произойти в любом месте. Автор статьи справедливо показывает, что попытка по текущему содержимому стека определить подпрограмму — это непродуманная ерунда. Например, идет подготовка параметров к вызову API. Выделили место, достаем очередной параметр — ошибка, неинициализированный указатель — исключение доступа. Опа, а в стеке еще просто мусор (туда еще ничего не поместили). Мусор начинает "исследоваться" ОС.
O>Если же исключение возникает изза жесткой ошибки защиты — изза неверно выделенной памяти или изза того что после расстрела стека исполнение пошло по мусорному коду, это означает что исполнение программы дальше невозможно. Баста, остается только позвать по LPC post-mortem дебаггер.
Для этого введен механизм обработчиков исключений. Задача ОС найти обработчик. Только, если она обработчик не нашла — тогда заканчивать задачу с сообщением. Домыслы фатальное-не фатальное исключение — это не дело ОС.
O>Потому что есть соглашения об адекватном валидном коде, которые несколько выше чем "аппаратно". И согласно которым стек должен всегда оставаться выровненным на 8 (а при вызове публичной функции, в ее прологе — на 16). Если он таковым вдруг не стал — значит код не валидный. Время любителей писать выверты на асме прошло. Теперь балом правит кодогенератор.
O>Это чисто измышления автора. Я лично понимаю разработчиков ОС. Факт того что стек оказался не выравнен на 8 указывает на то что исключене является фатальным, потому что в корректном коде такого произойти не должно. А значит лучше всего ничего не делать на этом стеке чтобы не наломать еще больших дров.
Выше "аппаратного" ничего нет. Требования кратности 16 дает не соглашение, а всего лишь используемые команды типа
movdqa xmm0,xmmword ptr [rsp+20h] — обращение к XMM и памяти. Они дают аппаратное исключение из-за невыровненного доступа.
Смешной штрих: чтобы внутри вызова стек был кратен 16, снаружи вызова он должен быть НЕ кратен 16.
Но автор статьи не из-за этого пострадал. Он согласен со всеми требованиями вызова функций. Но ему-то хотелось в момент исключения пошагового режима обращаться со стеком как он привык в Win32. А исключение пошагового режима превращается в фатальное из-за того, что какой-то чудак на букву М не может поверить, что в этот момент (просто выполнение очередной команды) стек используется не так как при вызове API.