cmovz

Тема в разделе "WASM.ASSEMBLER", создана пользователем sergegers, 9 май 2011.

  1. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    С виду простой вопрос, но что-то ничего не нашёл по этому поводу нигде. Вот кусок кода

    Код (Text):
    1.     invoke  IsBadReadPtr, edi, sizeof DWORD
    2.     xor     esi, esi
    3.     test    eax, eax
    4.     cmovz   esi, dword ptr [edi]            ; <- здесь access violation
    Регистры и флаги
    Код (Text):
    1. EAX = 00000001
    2. OV = 0 UP = 0 EI = 1 PL = 0 ZR = 0 AC = 0 PE = 0 CY = 0
    то есть получается, что указатель разыменовывается в любом случае, выполняется присвоение или нет. И если это так, то можно ли как-то обойти, не используя ветвление
     
  2. Ezrah

    Ezrah Member

    Публикаций:
    0
    Регистрация:
    22 мар 2011
    Сообщения:
    411
    Код (Text):
    1. dwNull  dd 0
    2.  
    3. invoke   IsBadReadPtr, edi, sizeof DWORD
    4. test    eax, eax
    5. cmovnz  edi, offset dwNull
    6. mov     esi, [edi]
     
  3. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    Cпасибо! А с чем связано разыменовывание указателя в любом случае, вы не знаете?
     
  4. gaeprust

    gaeprust New Member

    Публикаций:
    0
    Регистрация:
    2 май 2011
    Сообщения:
    188
    Нужно смотреть псевдокод в манах, вот для CMOVcc(x64 я опустил):
    Код (Text):
    1. temp <- SRC
    2. IF condition TRUE
    3.     THEN
    4.         DEST <- temp;
    5. FI;
    Тоесть вначале во временный регистр читается переменная, затем она в зависимости от условия переносится в RGP. Поэтому независимо от условия будет выполнен доступ к переменной, тоесть все проверки безопасности. Разумеется при этом генерится #AV, если проверки не прошли.
    Стоит заметить что если в IsBadReadPtr() передаётся нулевой указатель, то функция возвратит ноль, тоесть какбы успешно выполнится(аналогично как и в ядре ProbeForRead()).

    Можно использовать префикс rep:
    Код (Text):
    1.     invoke IsBadReadPtr, Esi, sizeof DWORD
    2.     test eax,eax
    3.     setz cl
    4.     movzx ecx,cl
    5.     rep lodsd
     
  5. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    Я просто не знал, что псевдокод описывает ситуацию и в случаях с исключениями

    а так не менее производительно?
     
  6. gaeprust

    gaeprust New Member

    Публикаций:
    0
    Регистрация:
    2 май 2011
    Сообщения:
    188
    sergegers
    Вы наверно шутите ?
    Какая оптимизация может быть, если вы в юзермоде, да есчо и винапи юзаете :lol:
     
  7. sergegers

    sergegers New Member

    Публикаций:
    0
    Регистрация:
    8 июн 2008
    Сообщения:
    172
    Понял, спасибо -)