|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Июн 23, 2004 19:53:12 · Поправил: volodya Тема уже немного измусолена, т.к. есть статья на сайте и куча комментариев к ней, кроме того, немножко есть и по форуму. Но я бы хотел подойти к вопросу с несколько другой стороны - со стороны математики. Единственная известная мне книга, которая обсуждает такие вещи для высокоуровневых языков - это Уоррен. Раздел 2-12. Overflow detection. Изначально рассматривается overflow при signed add/subtract. Далее цитата из Уоррена: "These formulas are perhaps interesting, but on most machines they would not be quite as efficient as the formulas that do not even use the carry bit (e.g., overflow = (x ТРОЙНОЕ_РАВНО y) & (s XOR x)for addition, and (x XOR y) & (d XOR x)for subtraction, where s and d are the sum and difference, respectively, of x and y)." То, что вызывает у меня смущение: 1) Я не понимаю, как Уоррен получил эти формулы, т.к. уж очень как-то резко он к ним пришел 2) Поэтому хотелось бы их проверить, но я не знаю, к стыду своему, как операцию ТРОЙНОЕ_РАВНО можно написать на С? ТРОЙНОЕ_РАВНО - это, кажется, операция равенства по модулю? Нет? 3) Кроме того, хотелось бы, что бы ассемблерщики проверили меня, т.к. тут предлагается универсальный способ для любой платформы, в том числе и такой, где нет ни CF, ни OF ни чего-то подобного... Теперь еще два определения: "Signed integer overflow of addition occurs if and only if the operands have the same sign and the sum has sign opposite to that of the operands." "For subtraction of multiword integers, the computation of interest is x - y - c where again c is 0 or 1, with a value of 1 representing a borrow-in. From an analysis similar to the above, it can be seen that overflow in the final value of x - y - c occurs if and only if x and y have opposite signs and the sign of x - y - c is opposite to that of x (or, equivalently, the same as that of y)." |
|
|
Дата: Июн 23, 2004 20:21:45 тройное равно - это вроде как "тождественно равно". Но это в математике.Насчёт платформы - у IBM была вроде как серия серверов с аппаратной защитой от переполнения буфера. |
|
|
Дата: Июн 23, 2004 20:24:04 По поводу "тройного равно": Тройное равно это побитовая эквивалентность. Если видим что к xor можно относится (помимо прочих трактовок как то сложение по модулю 2 или "или исключающее и") как к побитовому неравентву (т.е. в 1 ставится когда биты неравны а в 0 когда равны) то побитовая эквивалентность это: not ( x xor y) т.е. в один ставятся биты значения которых равно, а в 0 которых неравно. |
|
|
Дата: Июн 23, 2004 21:02:25 |
|
|
Дата: Июн 23, 2004 21:11:12 The Svin Не понимаю :( Все те зубодробительные примеры, что Уоррен приводит, у меня только уши в трубочку от них сворачиваются. Вот очень простой и доходчивый пример. Для UNSIGNED integer overflow: A + B overflows if: A + B < A И все кристально ясно. И все работает: unsigned int x = 0xFFFFFFFF, y = 0x20, s; bool is_overflow = false; if(x + y < x) is_overflow = true; |
|
|
Дата: Июн 23, 2004 21:12:06 Теперь пробую писать согласно тому, что вы посоветовали. Для SIGNED. int x = INT_MAX, y = 2, s; bool is_overflow = false; s = x + y; if((!(x^y))&(s^x)) is_overflow = true; Ноль на массу :( |
|
|
Дата: Июн 23, 2004 21:13:01 where again c is 0 or 1 |
|
|
Дата: Июн 23, 2004 21:17:06 НУ И ЧТО? Напиши, будь любезен, пример. Пример для signed integer overflow при сложении и вычитании. Чтобы до меня дошло :) |
|
|
Дата: Июн 23, 2004 23:55:45 Integer Overflow Vulnerabilities 32-bit integer overflow и на закуску Incorrect integer overflow detection in C code и Bob Tennent && Linus Torvalds unsigned long x, y, sum; int overflow = 0; sum = x+y; if (sum < x) overflow = 1; Works portably in C (but only with "unsigned" types that are guaranteed to have twos-complement behaviour and well-defined overflow semantics). And good compilers will notice that "overflow" is really just the carry flag, and optimize it. I don't remember if gcc counts as "good" in this case, but I doubt it ;) |
|
|
Дата: Июн 24, 2004 00:05:29 Shift Гуглить я и сам умею :( Все это я уже читал. Им всем до Уоррена как до китая раком. А код Торвальда уже написан выше. Так что туфта все это :( |
|
|
Дата: Июн 24, 2004 00:27:44 · Поправил: Shift volodya Короче, спать пора - но темка меня заинтересовала - как получу резалт по уоренну - отпишусь.Шас уже плохо соображаю :( |
|
|
Дата: Июн 24, 2004 00:53:08 · Поправил: Black_mirror volodya Результат проверки этих формул оказывается в самом старшем бите результата. (x ТРОЙНОЕ_РАВНО y) & (s XOR x) - произошло переполнение если знаки слагаемых одинаковые и знак суммы отличается от знака слагаемого. (x XOR y) & (d XOR x) - произошло переполнение если знаки уменьшаемого и вычитаемого разные и знак разности отличается от знака уменьшаемого. То есть должно быть так: if((~(x^y))&(s^x)&MIN_INT) is_overflow = true; |
|
|
Дата: Июн 24, 2004 01:06:02 Разобрался с беззнаковым умножением. Определение: "For multiplication, overflow means that the result cannot be expressed in 32 bits" Пример: unsigned int x = 0xFFFFFFFF, y = 0x20, z; bool is_overflow = false; z = x * y; if(y && z/y != x) is_overflow = true; Ассемблер: unsigned int x = 0xFFFFFFFF, y = 0x20, z; 00411A1E mov dword ptr [x],0FFFFFFFFh 00411A25 mov dword ptr [y],20h bool is_overflow = false; 00411A2C mov byte ptr [is_overflow],0 z = x * y; 00411A30 mov eax,dword ptr [x] 00411A33 imul eax,dword ptr [y] 00411A37 mov dword ptr [z],eax if(y && z/y != x) 00411A3A cmp dword ptr [y],0 00411A3E je main+51h (411A51h) 00411A40 mov eax,dword ptr [z] 00411A43 xor edx,edx 00411A45 div eax,dword ptr [y] 00411A48 cmp eax,dword ptr [x] 00411A4B je main+51h (411A51h) is_overflow = true; 00411A4D mov byte ptr [is_overflow],1 |
|
|
Дата: Июн 24, 2004 01:08:31 Black_mirror Спасибо тебе. Т.е. операция "ТРОЙНОЕ_РАВНО" на С может быть записана как: ~(x^y) А я перепутал битовое и логическое отрицание, баран. Еще раз спасибо! |
|
|
Дата: Июн 24, 2004 01:19:55 Для беззнаковых int (unsigned int) возможна проверка на переполнение еще перед вычислением. За теорией лезем в Уоррена. Код тут:
unsigned int x = 0x30, y = 0x20;
if(y && (x > 0xFFFFFFFF/y))
{
puts("The multiplication x*y will cause overflow\n");
}
Асм:
unsigned int x = 0x30, y = 0x20;
00411A1E mov dword ptr [x],30h
00411A25 mov dword ptr [y],20h
if(y && (x > 0xFFFFFFFF/y))
00411A2C cmp dword ptr [y],0
00411A30 je main+4Ch (411A4Ch)
00411A32 or eax,0FFFFFFFFh
00411A35 xor edx,edx
00411A37 div eax,dword ptr [y]
00411A3A cmp dword ptr [x],eax
00411A3D jbe main+4Ch (411A4Ch)
{
puts("The multiplication x*y will cause overflow\n");
00411A3F push offset string "The multiplication x*y will caus"... (42426Ch)
00411A44 call @ILT+1300(_puts) (411519h)
00411A49 add esp,4
}
|
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.085 |