avva: (moose)
[personal profile] avva
Прикольно - оказывается, инструкция idiv, деление со знаком, на x86 кидает исключение не только при делении на ноль, но и когда результат не помещается в регистр. А этого очень легко добиться, написав в C например INT_MIN / -1. Как мы помним, INT_MIN по модулю на единицу больше, чем INT_MAX; например, в 32-битных числах INT_MIN равно -2147483648, а INT_MAX равно 2147483647. Поэтому когда INT_MIN делят на -1, положительный результат не вмещается в 32 бита.

Само по себе это не катастрофа - ну кидает исключение, ну и подумаешь. Дело в том, однако, что про деление на ноль все знают и помнят, и проверяют перед попыткой делить. А против INT_MIN/-1 никто практически не защищается. Поэтому можно, например:

- крэшнуть компилятор (правда, игрушечный), PostgreSQL (не игрушечную) или антивирус;
- подвесить Windows 8;
- убить bash

Date: 2013-01-29 11:24 pm (UTC)
From: [identity profile] cema.livejournal.com
А ты черт! :-)

Date: 2013-01-29 11:39 pm (UTC)
From: [identity profile] http://users.livejournal.com/_zlot_/
Стоп сигнал
idiv берет два параметра когда первый параметр имеет в два раза больше битов чем второй, так что даже деление на два, при неправильных параметрах выдаст overflow

http://pdos.csail.mit.edu/6.828/2011/readings/i386/IDIV.htm

Date: 2013-01-29 11:58 pm (UTC)
From: [identity profile] archaicos.livejournal.com
Это так, но код на C(++) и не только на нём всегда фактически делит N бит на N бит (т.е. в [e|r]dx оказывается только знак делиМОГО).
Edited Date: 2013-01-30 03:41 am (UTC)

Date: 2013-01-30 12:07 am (UTC)
From: [identity profile] avva.livejournal.com
это верно, но при обычном делении int такая ситуация обычно не возникает, потому что первый аргумент, хоть и два раза длиннее с точки зрения инструкции, всего лишь исходный int, расширенный со знаком в дополнительный регистр. Поэтому INT_MIN/-1 - единственная возможность получить исключение при делении int-переменных.

Date: 2013-01-29 11:42 pm (UTC)
From: [identity profile] spamsink.livejournal.com
Это они зря. Microcode patch был бы полезен.

Date: 2013-01-29 11:45 pm (UTC)
From: [identity profile] avva.livejournal.com
Такое поведение во всех процессорах семьи начиная с 8086.

Date: 2013-01-29 11:49 pm (UTC)
From: [identity profile] spamsink.livejournal.com
Я не говорю, что это регрессия; я говорю, что это хорошо бы, наконец, поправить. Сочетание INT_MIN и -1 - единственный случай, когда результат не помещается в регистр, но он эквивалентен умножению на -1, которое прерывания не вызывает. Не вижу причин, по которым одна и та же операция с математической точки зрения должна вести себя по-разному в зависимости от команды.

Date: 2013-01-30 12:01 am (UTC)
From: [identity profile] archaicos.livejournal.com
Можно и вовсе отменить все проверки. MIPS сгенерит мусор (или не совсем мусор, не важно), если не сможет поделить, не вызывая исключений.

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 12:23 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 12:38 am (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 01:00 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 01:07 am (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 01:12 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 01:34 am (UTC) - Expand

(no subject)

From: [identity profile] netp-npokon.livejournal.com - Date: 2013-01-30 08:12 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 08:36 am (UTC) - Expand

(no subject)

From: [identity profile] meshko.livejournal.com - Date: 2013-01-30 03:09 am (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 05:27 am (UTC) - Expand

(no subject)

From: [identity profile] meshko.livejournal.com - Date: 2013-01-30 01:54 pm (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-31 04:02 am (UTC) - Expand

(no subject)

From: [identity profile] netp-npokon.livejournal.com - Date: 2013-01-30 08:23 am (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 08:26 am (UTC) - Expand

(no subject)

From: [identity profile] netp-npokon.livejournal.com - Date: 2013-01-30 08:32 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 04:10 pm (UTC) - Expand

(no subject)

From: [identity profile] netp-npokon.livejournal.com - Date: 2013-01-30 04:31 pm (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 08:38 am (UTC) - Expand

(no subject)

From: [identity profile] netp-npokon.livejournal.com - Date: 2013-01-30 08:52 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 08:57 am (UTC) - Expand

Date: 2013-01-30 04:31 am (UTC)
From: [identity profile] ircicq.livejournal.com
Поправить осмысленно нельзя просто потому, что CPU не имеет инструкции деления 32-bit на 32-bit.

IDIV всегда делит 64-bit на 32-bit (или 32 на 16, 16 на 8)
и overflow в таком случае обычное явление. Правильный компилятор не использует IDIV напрямую, всегда вызывается функция, проверяющая делимое и делитель на допустимый диапазон.
Edited Date: 2013-01-30 04:32 am (UTC)

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 05:29 am (UTC) - Expand

(no subject)

From: [identity profile] ircicq.livejournal.com - Date: 2013-01-30 06:19 am (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 07:48 am (UTC) - Expand

(no subject)

From: [identity profile] ircicq.livejournal.com - Date: 2013-01-30 08:08 am (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 08:24 am (UTC) - Expand

(no subject)

From: [identity profile] ircicq.livejournal.com - Date: 2013-01-30 08:37 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 08:48 am (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 03:49 pm (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 04:04 pm (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 04:18 pm (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 04:24 pm (UTC) - Expand

(no subject)

From: [identity profile] spamsink.livejournal.com - Date: 2013-01-30 04:44 pm (UTC) - Expand

(no subject)

From: [identity profile] huzhepidarasa.livejournal.com - Date: 2013-01-30 03:17 pm (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-30 05:45 am (UTC) - Expand

(no subject)

From: [identity profile] kray-zemli.livejournal.com - Date: 2013-01-30 02:35 pm (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-31 04:06 am (UTC) - Expand

(no subject)

From: [identity profile] kray-zemli.livejournal.com - Date: 2013-01-31 04:27 am (UTC) - Expand

(no subject)

From: [identity profile] archaicos.livejournal.com - Date: 2013-01-31 04:41 am (UTC) - Expand

Date: 2013-01-29 11:55 pm (UTC)
From: [identity profile] ahaxopet.livejournal.com
bash не падает, хотя версия вроде та же:

$ ($((-2**63/-1)))
-9223372036854775808: command not found
$ bash -version
GNU bash, version 4.2.37(1)-release (i686-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.


Доктор, что я делаю не так? :-)

Date: 2013-01-30 12:08 am (UTC)
From: [identity profile] gdt.livejournal.com
у вас 32 бита, почитайте последний коммент по ссылке про bash.

Date: 2013-01-30 12:09 am (UTC)
From: [identity profile] ahaxopet.livejournal.com
И верно, не заметил.

Date: 2013-01-30 12:09 am (UTC)
From: [identity profile] avva.livejournal.com
Запускаете на 32-битной системе (а они на 64-битной).

Date: 2013-01-30 02:25 pm (UTC)
From: [identity profile] oblomov-jerusal.livejournal.com
У меня 64-битная версия bash и zsh на дебиане ловит. Версия bash та же, что и у автора статьи, наверное дело в библиотеках

[2375]% bash
ilya@ilya-linux:~$ ($((-2**63/-1)))
Исключение в операции с плавающей точкой
ilya@ilya-linux:~$ exit
ilya-linux [bash] ~                                                                                               4:19
[2376:136]% bash -version
GNU bash, version 4.2.37(1)-release (x86_64-pc-linux-gnu)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
ilya-linux [bash -version] ~                                                                                      4:19
[2377]% ($((-2**63/-1)))
zsh: floating point exception  ( $((-2**63/-1)); )
ilya-linux [($((-2**63/-1)))] ~                                                                                   4:23
[2378:136]% 

(no subject)

From: [identity profile] oblomov-jerusal.livejournal.com - Date: 2013-01-30 02:33 pm (UTC) - Expand

Date: 2013-01-30 02:14 am (UTC)
From: [identity profile] bolk.livejournal.com
bolk@Bolk /$ ($((-2**63/-1)))
Floating point exception: 8
bolk@Bolk /$ bash --version
GNU bash, version 4.2.42(2)-release (i386-apple-darwin12.2.0)
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>

This is free software; you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.

Date: 2013-01-30 12:05 am (UTC)
From: [identity profile] ygam.livejournal.com
У меня Windows 8 не падает. Версия ядра 6.2.9200.16384 .

Date: 2013-01-30 12:16 am (UTC)
From: [identity profile] rezkiy.livejournal.com
у них 32 разрядная.

// Product: WinNt, suite: TerminalServer SingleUserTS
// Built by: 9200.16384.x86fre.win8_rtm.120725-1247

Date: 2013-02-01 06:15 pm (UTC)
From: [identity profile] molnij.livejournal.com
у меня 32-разрядная триальная послушно умерла.
сижу, ржу

Date: 2013-01-30 09:46 am (UTC)
From: [identity profile] janatem.livejournal.com
Про баш там что-то странное написано:

$ ($((-2**63/-1)))

Внешние скобки порождают дочерний баш и в нем исполняется содержимое. Это вроде логично: если команда рушит баш, то сдохнет внутренний, а внешний останется жить и нам об этом сообщит. Но дальше непонятно: двойные скобки вычисляют внутреннее выражение, а доллар исполняет результат как команду. То есть $((2+3)) — это то же самое, что исполнить команду 5, должно выдать 5: command not found. Правда, в данном примере, если баш дохнет, то до попытки запуска команды под долларом дело не доходит.

Всё же логичней запускать так:

$ ( ((-2**63/-1)) )

Date: 2013-01-30 11:34 am (UTC)
From: [identity profile] huzhepidarasa.livejournal.com
не совсем так. $((...)) выполняет арифметику, а двойные скобки без доллара отдельного смысла не несут.

Date: 2013-01-30 11:56 am (UTC)
From: [identity profile] janatem.livejournal.com
Вполне себе несут. Помимо побочного эффекта, ради которого был написан данный пример, в них можно означивать переменные (и, в частности, они могут использоваться в цикле for):

$ ((i=3+4)); echo $i

В вышеупомянутом примере доллар имел бы смысл в таком виде:

$ (echo $((-2**63/-1)))

Если туда подставить хорошее (не приводящее к ошибке) выражение, то так выводится результат выражения вместо вызова бессмысленной команды.

(no subject)

From: [identity profile] huzhepidarasa.livejournal.com - Date: 2013-01-30 03:12 pm (UTC) - Expand

Date: 2013-01-30 12:52 pm (UTC)
wizzard: (фото)
From: [personal profile] wizzard
че-то винда не падает. может это 32бит онли?

в обычном приложении, впрочем, эксепшен взлетает, факт

Date: 2013-01-30 12:54 pm (UTC)
From: [identity profile] avva.livejournal.com
Это не знаю, сам не пробовал, у меня нет Windows 8.

На C# то же самое

Date: 2013-01-30 07:04 pm (UTC)
From: [identity profile] brandt1.livejournal.com
Проверял в Visual Studio 2012, operational system Windows 2008.
Интересно, а кому это надо было - делить INT_MIN/-1?

December 2025

S M T W T F S
  123 4 56
78 9 10 11 1213
1415 1617181920
21 22 23 24 2526 27
28293031   

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Dec. 28th, 2025 02:18 pm
Powered by Dreamwidth Studios