есть такой листинг: Код (Text): .text:0001050E 00C xor ebx, ebx .text:00010510 00C push esi ; DeviceObject .text:00010511 010 push ebx ; Exclusive .text:00010512 014 push 80h ; DeviceCharacteristics .text:00010517 018 push 22h ; DeviceType .text:00010519 01C push ebx ; DeviceName .text:0001051A 020 push 114h ; DeviceExtensionSize .text:0001051F 024 push [ebp+DriverObject] ; DriverObject .text:00010522 028 call ds:__imp__IoCreateDevice@28 ; __declspec(dllimport) IoCreateDevice(x,x,x,x,x,x,x) .text:00010528 010 cmp eax, ebx .text:0001052A 010 mov [ebp+DeviceObject], eax .text:0001052D 010 jl short loc_1057B И вот что странно, после выполнения IoCreateDevice, как видно из листинга ebx = 0, eax - возвращаемый параметр(NTSTATUS) который может иметь 4 значения: Код (Text): STATUS_SUCCESS equ 0 STATUS_INSUFFICIENT_RESOURCES equ 0C000009Ah STATUS_OBJECT_NAME_EXISTS equ 40000000h STATUS_OBJECT_NAME_COLLISION equ 0C0000035h Выходит что eax всегда >= ebx, и знаково и беззнаково те получается переход на short loc_1057B никогда не осуществляется. Как это так? Заранее спасибо.
letopisec Я извинаюсь за офтоп, и прошу следующее не принимать за оскорбление или насмешку(у меня и в мыслях такого не было), но letopisec читается как "летописек" и у меня сразу возникает ассоциация, которая так и подмывает поставить пробел после 4-й буквы. Раз уж используешь транслит, то может лучше писать letopisets?
S_T_A_S_ Это что, по принципу: "Когда нельзя, но очень хочется, то можно". А однозначность есть в этом или нет? Если у меня есть такое: Код (Text): mov eax,3221225525 cmp eax,0 jg @MoreThen то я на метку @MoreThen никак не могу попасть, всё время пролетаю мимо (. Так всё-таки, больше или меньше? Как попасть на @MoreThen?
Однозначность обязательно есть - это ж компьютер. Смотрим, какие флаги используются в Jcc и какие устанавливаются предыдущей инструкцией. JG - переход происходит, если ZF=0 и SF=OF. ZF при вычитании нуля устанавливается только, если операнд 0, т.е. в данном случае флаг булет равен 0. OF - флаг переполнения, он НЕ будет установлен, т.к. переполнение не может произойти при вычитании 0. SF - всегда равен старшему биту результата, т.е. в данном случае 1. Т.е. получим ZF=0 и SF=1 <> OF=0. Поэтому переход не происходит. При такой проверке подразумевается, что операнд - signed, т.е. C0000035 рассматривается как отрицательное число. Если необходимо его рассматривать как положительное, то нужно делать JA. (CF=0 ZF=0) Или JNZ, т.к. при вычитании 0 заём не может произойти в принципе и любое число не равное 0, является > 0.
Это все понятно и правильно, если заранее известно, знаковое число или нет. А если заранее неизвестно, то ja ошибается на знаковых, jg - на беззнаковых, так теперь надо получается две проверки, первая - на js и в зависимости от результата первой проверки выбирать, какая проверка будет вторая: jg или ja. Так? Код (Text): mov ecx, Var test ecx,ecx js @Signed cmp ecx,5 ja @MoreThen ... ... @Signed: cmp ecx,5 jg @MoreThen ... ...
cresta Такая проверка может не подойти т.к. может попасться беззнаковое длиной 32-бита у которого старший бит тоже будет установлен.
Toxic Не обращай внимания cresta Это всё похоже на провакацию. Во первых по числу C0000035 нельзя сказать знаковое оно или нет. А во вторых test ecx,ecx - это проверка на 0, а не отрицательность. И в третьих, если всё это не провакация, мне кажется, ты путаешь два понятия: знаковое число и отрицательное. Если беззнаковое, то C0000035 это C0000035 Если знаковое, то C0000035 = 80000000(это минус) | (~(40000035)+1) - это значение) = -3FFFFFCC команда mov eax, C0000035h cmp eax, 0 jg Label ; перехода не будет ja Label ; переход будет
letopisec Во первых по числу C0000035 нельзя сказать знаковое оно или нет. В контексте команды - можно. Сам же пример и привел ja - без знака jg - со знаком
letopisec Да, это и есть провокация , я поэтому и написал 3221225525 а не C0000035h. Число C0000035h меня не интересует, интересует 3221225525 Я знаю, что такое положительные и отрицательные числа. А что из себя представляют "знаковые" и "беззнаковые" числа? Почему процессор моё положительное число 3221225525 превращает в "знаковое" -1073741771 ? Оттого, что я не уложился в отведённый диапазон 2^31-1? Как подстраховаться если заранее не известна величина числа? Проверять старший бит? А может число отрицательное и меньше 2^31 и бит стоит по праву? DaemoniacaL Ну хорошо, тогда конкретно так: 1) Eсть y=(2^32-1)*sin(x), и a=(2^32-1)*cos(b).Как правильно сравнить y и a ?
cresta типа 3221225525 десятичное = C0000035h шеснадцатиричное в еах грузим 3221225525, если оно 16тиричное, то в еах оно явно не поместится, вывод - оно 10тичное. А следовательно cresta тебя интересует именно >1) Eсть y=(2^32-1)*sin(x) Положим sin(x) = 1 => y = FFFFFFFF Теперь sin(x) = -1 => y = 100000001 Не настораживает что в последнем примере число 33-х разрядное?
letopisec Подожди умывать руки С какой это радости при х=-1 y получается 33-х разрядным??? Y= 4294967295 *(-1)= -4294967295, или чтобы в разрядах: -2^32-1 q_q Народ, вы не уходите от ответа . Случай y=M*sin(x), и a=N*cos(b). Где M<>N , и M и N -простые числа (или взаимно простые числа) в диапазоне от 2^31 до 2^32-1. Как сравнить y и a если общего множителя нет? Или вот такой пример:переменная y в результате некоторых вычислений приняла значение 4294967295, переменная a в результате вычислений приняла значение -1 Код (Text): mov eax,y mov eсx,a cmp eax,ecx je @Equ И программа переходит на @Equ, хотя 4294967295 <> -1. Предвижу ответ, что я не уложился в диапазон –2147483648...+2147483647. Как узнать, что я не укладываюсь в диапазон и результат вычисления - большое положительное число а не маленькое отрицательное и мне надо переключиться на другой алгоритм проверки? Флаги мне в этом никак не помогают.
-2^32-1 - это 32 разряда на значение + 1 на знак. Итого: 33 А чем отличается представление 4294967295(32-х разрядное знаковое) от -1(32-х разрядное знаковое)?