· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.A&O —› Overflow detection

. 1 . 2 . 3 . >>

Посл.отвђт Сообщен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 
	}

. 1 . 2 . 3 . >>


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.085