информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяВсе любят мед
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Простое пробивание рабочего/провайдерского... 
 400 уязвимостей в процессорах Snapdragon 
 Яндекс неуклюже оправдался за установку... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
Углубился я в дизассемблер 10.03.05 04:30  Число просмотров: 2157 [Heller]
Автор: Heller <Heller> Статус: Elderman
<"чистая" ссылка>
Для начала простой пример. Дано: a - int, проверка условия - if (a) (пример немного не в тему - привожу для дальнейшего сравнения):

cmp dword ptr [a (004225d8)],0
je main+25h (00401035)

Те же условия, но проверка (!a):

cmp dword ptr [a (004225d8)],0
jne main+25h (00401035)

При отрицании единственное что изменилось, это проверка с JE на JNE. В общем, именно так, как я писал уже выше.

Заменив в этих примерах "int a" на "int *a" не зменилось вообще ничего - код остался совершенно таким же. Компилятор при построении экзэшника не сделал разницы между указателем и обычным int'ом.

Вообще для любых целых типов он просто урезает/дополняет значение до dword. Например, для char'а это инструкция movsw.

Для вещественных чисел алгоритм более мудрёный:

fld dword ptr [a (00426968)]
fcomp dword ptr [__real@4@00000000000000000000 (0042301c)]
fnstsw ax
test ah,40h

В этом случае сравнение идёт по регистру SWR (пример дан для float). Всякие doubl'ы и прочие, видимо, работают аналогично, но я не стал разбираться - не то сейчас интересно. Кстати, для сравнений он всегда, не только с вещественными числами, но и с целыми, испольует test. Исключение составляет только тот случай, когда под переменную изначально выделено 4 байта - в этом случае используется cmp. Ну да это я так, к слову.

В общем, как это всё работает, понятно. Теперь про сравнения "==". Начну с простого int'аб сравнивая его с "0":

cmp dword ptr [a (00426968)],0
jne main+25h (00401035)

Для "!=" jne меняется на je. То есть, вообще говоря, компилятору исключительно пофик как именно идёт сравнение. "0" он и есть "0", а сравнение идёт обычным cmp, приводя изначально любое данное к dword.

Для полноты картины упомяну и про вещественные типы. В случае сравнения "==0" или "!=0" код получается такой же, как и приведённый выше (там где сравнивается SWR). А вот если проверка идёт уже с конкретным значением, например "==1", то компилятор уже не заморачивается и использует всё тот же cmp.

Теперь сравнение указателей. Приведу сразу общий случай:

Код на Си:
int *a,*b;
void main() {
if (a==b) {return;}
}

Соответственно на АСМе:
mov eax,[a (00426b94)]
cmp eax,dword ptr [b (00426b98)]
jne main+29h (00401039)
jmp main+2Bh (0040103b)

Теперь изврат:
if (a==((void *)0))
На АСМе. Вы будете смеяться:
cmp dword ptr [a (00426b94)],0
jne main+25h (00401035)

Тот же результат даёт сравнение с NULL. Причём совершенно пофик, что именно я с ним сравниваю, указатель или "обыкновенный" тип. И даже скажу больше: при сравнении с NULL типа float мы получаем всё те же самые fld и fcomp.

Получается, что следующие записи эквивалентны: (a), (a!=0), (a!=NULL). От следующих: (!a), (a==0), (a==NULL) они отличаются только иструкцией je вместо jne. При этом Си'шный тип (указатель/не указатель, char/не char) вообще оказывается не существенным.
<programming> Поиск 








Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2020 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach