Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Целочисленное деление на 0, Как фиксируется аппаратно 
V
    Опции темы
FCM
Дата 31.10.2009, 16:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



В каком регистре CPU фиксируется деление целого на ноль того же типа?
PM MAIL   Вверх
AndNot
Дата 1.11.2009, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 28.2.2008

Репутация: нет
Всего: нет



Ни в каком. При делении на ноль процессор генерирует исключение. Перехватывай INT 0. На 8086 в него передается адрес следующей за делением команды, а в 286-м и выше - адрес команды деления на ноль.
PM MAIL   Вверх
Mikl_
Дата 2.11.2009, 06:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 9.11.2007

Репутация: 6
Всего: 14



FCM
В операциях деления предпола­гается, что частное значительно меньше, чем делимое. Деление на 1, например, может также вызвать переполнение, так как частное равно дели­телю, поэтому рекомендуется следующее пра­вило: если делитель – байт, то его значение должно быть меньше чем старший байт делителя (содер­жимое регистра ah); если делитель – двойное слово, то его значение долж­но быть меньше чем старшее двойное слово делителя (содержимое реги­стра edx). Деление на 0  сработает при div/idiv ah, div/idiv dx, div/idiv edx при любом содержимом ah/dx/edx smile 
PM MAIL   Вверх
FCM
Дата 11.11.2009, 09:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



Т.е. получается, что исключение целочисленого деления на ноль генерируется CPU в рез-те операций, которые в ассемблированном виде имеют вид  " div/idiv ah, div/idiv dx, div/idiv edx при любом содержимом ah/dx/edx" и ни в каком флаге CPU это событие не отражается?

(С другой стороны целочисленный overflow фиксируется CPU, но самостоятельно CPU такое исключение не генерит.)


Это сообщение отредактировал(а) FCM - 11.11.2009, 09:33
PM MAIL   Вверх
Mikl_
Дата 11.11.2009, 12:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 9.11.2007

Репутация: 6
Всего: 14



FCM
Вы ответили моим ответом на свой вопрос -- какой ответ вы еще ждете? smile 
PM MAIL   Вверх
FCM
Дата 11.11.2009, 16:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



Цитата(Mikl_ @  11.11.2009,  12:58 Найти цитируемый пост)
Вы ответили моим ответом на свой вопрос -- какой ответ вы еще ждете?

Ваш ответ несколько необычен для моего восприятия (поскольку в основном программирую на языках высокого уровня), поэтому и "переспросил".

PS/
есть одна древняя притча, мораль которой такова: "Даже в самой очевидной ситуации есть хотя бы один незнакомый аспект". А уж к программированию это относится стократно. 
PM MAIL   Вверх
AndNot
Дата 16.11.2009, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 28.2.2008

Репутация: нет
Всего: нет



Цитата(FCM @  11.11.2009,  09:30 Найти цитируемый пост)
Т.е. получается, что исключение целочисленого деления на ноль генерируется CPU в рез-те операций, которые в ассемблированном виде имеют вид  " div/idiv ah, div/idiv dx, div/idiv edx при любом содержимом ah/dx/edx" и ни в каком флаге CPU это событие не отражается?

В корне неверно. При чем тут "div ah" и прочие? Тебе это привели только для примера возникновения переполнения. Пойми одну простую вещь. Делимое всегда в два раза больше делителя, а результат всегда должен быть равен, по размеру, делителю. Поэтому возможны случаи возникновения переполнения результата. Для примера раздели 600 на 2. Если использовать команду деления на БАЙТ, то возникнет переполнение (300 не уместится в регистр AL). Если же делить на СЛОВО, то переполнения не будет, поскольку 300 легко умещается в регистр AX.

Цитата(FCM @  11.11.2009,  09:30 Найти цитируемый пост)
и ни в каком флаге CPU это событие не отражается?
Выставляется флаг OVERFLOW, в регистре флагов. Но тебе он вряд ли поможет, поскольку будет доступен только в обработчике исключения, а тот по умолчанию выведет сообщение о делении на ноль и подвесит программу.

Цитата(FCM @  11.11.2009,  09:30 Найти цитируемый пост)
С другой стороны целочисленный overflow фиксируется CPU, но самостоятельно CPU такое исключение не генерит
Это совершенно разные ситуации, поэтому и обрабатываются по разному.

PM MAIL   Вверх
FCM
Дата 16.11.2009, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 461
Регистрация: 30.3.2009

Репутация: нет
Всего: 9



Цитата(AndNot @  1.11.2009,  00:56 Найти цитируемый пост)
Ни в каком.


Цитата(AndNot @  16.11.2009,  15:13 Найти цитируемый пост)
Выставляется флаг OVERFLOW, в регистре флагов.


Так как же на самом деле?

Цитата(AndNot @  16.11.2009,  15:13 Найти цитируемый пост)
Выставляется флаг OVERFLOW, в регистре флагов. Но тебе он вряд ли поможет, поскольку будет доступен только в обработчике исключения, а тот по умолчанию выведет сообщение о делении на ноль и подвесит программу.


Меня как раз все это интересует со  стороны С++ и со стороны исключений (SEH, C++)

PM MAIL   Вверх
111u3
Дата 17.11.2009, 05:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 31.8.2009
Где: Омск

Репутация: нет
Всего: нет



FCM, если обратится к интеловским манам то можно найти следующее; Overflow is indicated with the #DE (divide error) 
exception rather than with the CF flag. т.е. тебе остается ловить это исключение.
PM MAIL ICQ   Вверх
AndNot
Дата 17.11.2009, 12:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 28.2.2008

Репутация: нет
Всего: нет



Цитата(FCM @  16.11.2009,  19:30 Найти цитируемый пост)
Так как же на самом деле?
На самом деле сам факт всплытия обработчика исключения 0 свидетельствует о некорректной операции деления и проверять флаги уже нет нужды. Что и делают стандартные обработчики - просто прикрывают программу (или вешают комп). Можно конечно в обработчике проанализировать опкод и если возможно, то выполнить деление повторно, расширив разрядность операндов. Но это рискованно - еще одна ошибка и получим другое исключение - двойной отказ, а это уже серьезно, поскольку малейшая ошибка уже приведет к отключению процессора.
Цитата(FCM @  16.11.2009,  19:30 Найти цитируемый пост)
Меня как раз все это интересует со  стороны С++ и со стороны исключений (SEH, C++)
Ну так с этого и надо начинать. Флаги тебе здесь не помогут, поскольку SEH универсален и всплывает при любом исключении, а не только при делении на ноль. Тут тебе скорее нужно маны по винде изучать, а не хард. Могу только предположить, что самым простым вариантом будет анализ опкода, что вызвал исключение.
PM MAIL   Вверх
111u3
Дата 17.11.2009, 15:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 31.8.2009
Где: Омск

Репутация: нет
Всего: нет



AndNot, ну допустим если быть точным двойной отказ получить в этом случае крайне трудно - так он появляется только если во время одного исключения словили другое(вернее из другого класса) это я точно говорю (это так прописано в манах и работает на практике) ну а SEH и настроить можно равно как и другие инструменты для подобных ситуаций.
PM MAIL ICQ   Вверх
AndNot
Дата 18.11.2009, 05:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 55
Регистрация: 28.2.2008

Репутация: нет
Всего: нет



Цитата(111u3 @  17.11.2009,  15:07 Найти цитируемый пост)
это я точно говорю
А я разве не об этом говорил? smile 
Цитата(111u3 @  17.11.2009,  15:07 Найти цитируемый пост)
ну допустим если быть точным двойной отказ получить в этом случае крайне трудно
Это легче чем кажется. Чем сложнее код, тем больше вероятности наличия в нем скрытых ошибок ;) За примерами далеко ходить не надо - в соседней теме дал простейший код, но даже не заметил опечатки с условным переходом. И это обычное дело, когда явную ошибку в упор не видишь и проявится она необязательно сразу. Поэтому грамотно разрулить ситуацию в самом обработчике исключения довольно сложно (а значит рискованно) и применяют альтернативные методы, в частности обработчик только фиксирует ситуацию, а обрабатывается она уже вне обработчика (что автоматом исключает вероятность двойного отказа). Это не только безопаснее, но и более выгодно с точки зрения альтернативных путей решения ситуации. Например таким макаром в простом паскале легко обходятся деления на ноль (ну не совсем легко, приходится использовать асм, либо инлайн вставки). Но все эти альтернативные обработчики (и в паскале и SEH) сами по себе не являются обработчиками исключительных ситуаций, это скорее постобработчики, всего лишь фичи языка и ОС.
PM MAIL   Вверх
Mikl_
Дата 18.11.2009, 06:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 537
Регистрация: 9.11.2007

Репутация: 6
Всего: 14



FCM, а вот так нельзя? Допустим делитель в ebx
Код
test ebx,ebx
jz err_div0
div ebx
 smile 
PM MAIL   Вверх
111u3
Дата 18.11.2009, 08:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 80
Регистрация: 31.8.2009
Где: Омск

Репутация: нет
Всего: нет



AndNot, не совсем верно - получить 2 исключение ни во время обработки 1, а сразу после него перед заходом в обработчик и то для каждого конкретного случая есть свои оссобенности. Я вон поток #GP ловил один за другим и не разу двойного не было. а вот когда во время исключения #GP я #PG хватанул тогда проц и перезагрузился причем без захода в обработчики #GP и #PG(на двойном исключении у меня тогда ничего не стояло). + никто не заставляет автора поста лезть в обработчики idt - его ос туда не пустит(по крайней мере за так). А SEH пишут когда данное событие не должно происходить но происходит по причине "отсутствия настроения у ос рано утром". И еще не все обработчики допускают обработку во вне. 

респект Mikl_ - зачем гемороится с исключениями когда можно ловить 0 до деления.
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Asm: Общие вопросы"
MAKCim
  • Проставьте несколько ключевых слов темы, чтобы её можно было легче найти.
  • Не забывайте пользоваться кнопкой КОД.
  • Телепатов на форуме нет! Задавайте чёткий, конкретный и полный вопрос. Указывайте полностью ошибки компилятора и компоновщика.
  • Новое сообщение должно иметь прямое отношение к разделу форума. Флуд, флейм, оффтопик запрещены.
  • Категорически запрещается обсуждение вареза, "кряков", взлома программ и т.д.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, MAKCim.

 
 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Asm: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0810 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.