Выполнимо ли условие?

Тема в разделе "WASM.RESEARCH", создана пользователем letopisec, 15 авг 2004.

  1. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    есть такой листинг:
    Код (Text):
    1.  
    2. .text:0001050E 00C                 xor     ebx, ebx
    3. .text:00010510 00C                 push    esi             ; DeviceObject
    4. .text:00010511 010                 push    ebx             ; Exclusive
    5. .text:00010512 014                 push    80h             ; DeviceCharacteristics
    6. .text:00010517 018                 push    22h             ; DeviceType
    7. .text:00010519 01C                 push    ebx             ; DeviceName
    8. .text:0001051A 020                 push    114h            ; DeviceExtensionSize
    9. .text:0001051F 024                 push    [ebp+DriverObject] ; DriverObject
    10. .text:00010522 028                 call    ds:__imp__IoCreateDevice@28 ; __declspec(dllimport) IoCreateDevice(x,x,x,x,x,x,x)
    11. .text:00010528 010                 cmp     eax, ebx
    12. .text:0001052A 010                 mov     [ebp+DeviceObject], eax
    13. .text:0001052D 010                 jl      short loc_1057B
    14.  




    И вот что странно, после выполнения IoCreateDevice, как видно из листинга ebx = 0, eax - возвращаемый параметр(NTSTATUS) который может иметь 4 значения:
    Код (Text):
    1.  
    2. STATUS_SUCCESS              equ 0
    3. STATUS_INSUFFICIENT_RESOURCES equ 0C000009Ah
    4. STATUS_OBJECT_NAME_EXISTS     equ 40000000h
    5. STATUS_OBJECT_NAME_COLLISION  equ 0C0000035h
    6.  




    Выходит что eax всегда >= ebx, и знаково и беззнаково

    те получается переход на short loc_1057B никогда не осуществляется.



    Как это так?



    Заранее спасибо.
     
  2. DaemoniacaL

    DaemoniacaL New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2003
    Сообщения:
    42
    Адрес:
    Russia
    STATUS_OBJECT_NAME_COLLISION < 0, следовательно переход возможен
     
  3. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    сенкс, проглядел, что начинается, С а не 0

    тупил уже полчаса наверное ;)
     
  4. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Я вот тоже решил немного потупить:

    Число 3221225525 больше или меньше нуля?
     
  5. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Больше!

    Но старший бит равен 1, значит может рассматриваться как отрицательное.
     
  6. Toxic

    Toxic New Member

    Публикаций:
    0
    Регистрация:
    5 сен 2003
    Сообщения:
    19
    Адрес:
    Ukraine
    letopisec

    Я извинаюсь за офтоп, и прошу следующее не принимать за оскорбление или насмешку(у меня и в мыслях такого не было), но letopisec читается как "летописек" и у меня сразу возникает ассоциация, которая так и подмывает поставить пробел после 4-й буквы. Раз уж используешь транслит, то может лучше писать letopisets?
     
  7. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    S_T_A_S_







    Это что, по принципу: "Когда нельзя, но очень хочется, то можно". А однозначность есть в этом или нет? Если у меня есть такое:
    Код (Text):
    1.     mov eax,3221225525
    2.     cmp eax,0
    3.     jg @MoreThen




    то я на метку @MoreThen никак не могу попасть, всё время пролетаю мимо :dntknw:(. Так всё-таки, больше или меньше? Как попасть на @MoreThen?
     
  8. DaemoniacaL

    DaemoniacaL New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2003
    Сообщения:
    42
    Адрес:
    Russia
    cresta

    Используй ja вместо jg
     
  9. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Однозначность обязательно есть - это ж компьютер.

    Смотрим, какие флаги используются в 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.
     
  10. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Это все понятно и правильно, если заранее известно, знаковое число или нет. А если заранее неизвестно, то ja ошибается на знаковых, jg - на беззнаковых, так теперь надо получается две проверки, первая - на js и в зависимости от результата первой проверки выбирать, какая проверка будет вторая: jg или ja. Так?
    Код (Text):
    1.     mov ecx, Var
    2.     test ecx,ecx
    3.     js @Signed
    4.     cmp ecx,5
    5.     ja @MoreThen
    6.     ...
    7.     ...
    8. @Signed:
    9.     cmp ecx,5
    10.     jg @MoreThen
    11.     ...
    12.     ...
     
  11. pas

    pas New Member

    Публикаций:
    0
    Регистрация:
    18 апр 2003
    Сообщения:
    330
    Адрес:
    Russia
    cresta

    Такая проверка может не подойти т.к. может попасться беззнаковое длиной 32-бита у которого старший бит тоже будет установлен.
     
  12. DaemoniacaL

    DaemoniacaL New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2003
    Сообщения:
    42
    Адрес:
    Russia
    cresta

    Это все понятно и правильно, если заранее известно



    Обычно это известно всегда :)
     
  13. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Toxic

    Не обращай внимания ;)



    cresta

    Это всё похоже на провакацию. ;)



    Во первых по числу C0000035 нельзя сказать знаковое оно или нет.



    А во вторых

    test ecx,ecx - это проверка на 0, а не отрицательность.



    И в третьих, если всё это не провакация, мне кажется, ты

    путаешь два понятия: знаковое число и отрицательное.



    Если беззнаковое, то C0000035 это C0000035

    Если знаковое, то C0000035 = 80000000(это минус) | (~(40000035)+1) - это значение) = -3FFFFFCC



    команда



    mov eax, C0000035h

    cmp eax, 0

    jg Label ; перехода не будет

    ja Label ; переход будет
     
  14. DaemoniacaL

    DaemoniacaL New Member

    Публикаций:
    0
    Регистрация:
    1 авг 2003
    Сообщения:
    42
    Адрес:
    Russia
    letopisec

    Во первых по числу C0000035 нельзя сказать знаковое оно или нет.

    В контексте команды - можно. Сам же пример и привел



    ja - без знака

    jg - со знаком
     
  15. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    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 ?
     
  16. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    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-х разрядное?
     
  17. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    ну а раз провакация ;)... я умываю руки
     
  18. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    cresta

    Как правильно сравнить y и a ?

    Для начала сократить общий множитель.
     
  19. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    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):
    1.     mov eax,y
    2.     mov eсx,a
    3.     cmp eax,ecx
    4.     je @Equ


    И программа переходит на @Equ, хотя 4294967295 <> -1.

    Предвижу ответ, что я не уложился в диапазон –2147483648...+2147483647. Как узнать, что я не укладываюсь в диапазон и результат вычисления - большое положительное число а не маленькое отрицательное и мне надо переключиться на другой алгоритм проверки? Флаги мне в этом никак не помогают.
     
  20. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228




    -2^32-1 - это 32 разряда на значение + 1 на знак. Итого: 33







    А чем отличается представление 4294967295(32-х разрядное знаковое) от -1(32-х разрядное знаковое)?