LINUX.ORG.RU
решено ФорумTalks

[нытик-тред][в пустоту]Зачем?

 


0

1

курю сейчас интеловские маны, и вот что доставляет. пусть у нас есть такой код:

movw $0xffff,%ax
divb 0xa
В мане написано

Unsigned divide AX by r/m8,with result stored in AL <-Quotient, AH <-Remainder

Но тогда тот код, который я написал выше, должен вызывать исключение переполнения. Так вот в чём вопрос. Почему бы не сделать так, чтобы результат помещался в тот же регистр (той же разрядности)? За что они так показали программистов? Получается, что в половине случаев, деля на единицу, мы получаем исключение. Бред какой-то. Какой вообще это придумал?

★★★★★

Ответ на: комментарий от fads

вообще-то да, так оно и делается. но это как-то не по-человечески, когда разрядность для частного в два раза меньше делимого

luke ★★★★★
() автор топика
Ответ на: комментарий от fads

так оно наверное есть: нужно только угадать, для каких аргументов операция выполнится, а для каких нет. что по-идее не должно лежать на программисте (эх, вот поэтому никто на асме и не пишет арифметику)

luke ★★★★★
() автор топика
Ответ на: комментарий от fads

одинаковые мнемоники. А директивы на то и директивы, чтобы быть разными. Они от процессора не зависят. в intel-синтаксисе тип операнда распознаётся ассемблером, тогда как в AT&T-синтаксисе тип операнда указывает программист.вот и все различия-то. Ну да, ещё поменяли местами приёмник и источник, ещё что-то там сделали - какая разница? Содержание одно и тоже, бинарный код одинаков

luke ★★★★★
() автор топика

пользуясь случаем, попрошу помощи в inline asm:
нужно прочитать FLAGS в переменную, делаю pushf, movl (%rbp), %eax. как загрузить содержимое eax в переменную?

fads ★★
()
Ответ на: комментарий от luke

на самом деле надо наверное писать не pushf, а pushfd - помещаем регистр eflags

luke ★★★★★
() автор топика
Ответ на: комментарий от anon_666

тут такое дело: получается, что команда div не нужна в таком виде, в котором она сделана (я имею ввиду для деления, например, слова на байт, слово на слово она поделит нормально). То есть есть фича, но для того, чтобы ею воспользоваться, нужно проверить делимое и делитель. Проще самому реализовать деление в таком случае.

luke ★★★★★
() автор топика
Ответ на: комментарий от luke

>нужно проверить делимое и делитель

Вероятно, компилятор проверит и использует это при возможности. И вероятно, реализовать это в проце «ничего не стоило».

anon_666
()
Ответ на: комментарий от luke

>(эх, вот поэтому никто на асме и не пишет арифметику)

Раньше писали. Сейчас целочисленная арифметика нужна не так часто, и то наверняка найдутся нужные simd-инструкции.

madcore ★★★★★
()
Ответ на: комментарий от madcore

ну вот да, пора отходить от калькуляторов

luke ★★★★★
() автор топика
Ответ на: комментарий от anon_666

>Вероятно, компилятор проверит и использует это при возможности.

ага, щас. как он проверит содержимое регистра в процессе ассемблирования (ну разве что только явное задание значения). Только в процессе выполнения.

Кстати, по идее в 8086 можно написать свой обработчик прерывания divizion by zero, который будет проверять значения регистров и если в делителе не ноль, то что-нибудь да и написать. В i386 уже сложнее - нужно добавлять функционал в ОС. Ну с linux это ещё нормально, но вот с сами-знаете-чем проблема.

luke ★★★★★
() автор топика
Ответ на: комментарий от luke

Просто ты нашел несуществующую проблему.
В обычных ситуациях, когда используется целочисленное деление, операнды приводятся к одинаковой разрядности. Т.е. в приведенном тобой примере восьмибитного деления в старшем регистре делимого(ah) всегда будет 0. Если бы было необходимо разделить именно 16-битное значение, то использовалось бы 32-разрядное деление(а в dx был бы 0). Соответственно, исключение может возникнуть только при делении на 0.
Когда делят именно 16бит на 8 - то только когда точно известно, что результат будет в допустимых приделах.

madcore ★★★★★
()
Ответ на: комментарий от madcore

>Когда делят именно 16бит на 8 - то только когда точно известно, что результат будет в допустимых приделах.

вот собственно когда это известно? Приведи пример, когда можно использовать деление 16-разрядного регистра на 8-разрядный? И да, без непосредственных операндов!

Я считаю такие фичи нужно выпиливать, потому что не нужны.

luke ★★★★★
() автор топика
Ответ на: комментарий от madcore

так не проще ли просто увеличить разрядность операции?

P.S. скорее всего ты прав, проблема на пустом месте. Зато я всё-таки разобрался в этом делении. Или мне кажется?

luke ★★★★★
() автор топика
Ответ на: комментарий от luke

>так не проще ли просто увеличить разрядность операции?

Больше разраядность - больше тактов наделение. Если допустим, есть массив данных, значения кторых не превосходит 0x200, а поделить надо на 3. Профит?

madcore ★★★★★
()
Ответ на: комментарий от madcore

а, ну если для этого. тогда и массив 1x200 - огромный.

только вот команда div выполнялась для 8-ми разрядного операнда минимум 80 тактов, для 16-и разрядного - 150 тактов. Эффективней писать деление столбиком наверное.

luke ★★★★★
() автор топика
Ответ на: комментарий от Yareg

только для этого предварительно нужно покопаться в коде и усечь «идею» разработки этой самой ОС. А 8086 можно не заморачиваться на тему исключений.

luke ★★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.