Содержание статьи
- Идентификация условных операторов
- Типы условий
- Наглядное представление сложных условий в виде дерева
- Исследование конкретных реализаций
- Сравнение вещественных чисел
- Условные команды булевой установки
- Идентификация типов с помощью условий
- Прочие условные команды
- Команды условного перехода
- Команды условной пересылки
- Булевы сравнения
- Итоги
if — then — else
и разберемся, как компилятор интерпретирует подобные конструкции.Раньше мы уже встречались с условным ходом выполнения программ, однако ограничивались короткими описаниями команд и поверхностным разбором выполняемых ими операций. Управляемый ход выполнения, без сомнения, самая важная веха развития программирования своего времени и затмевает многие последующие, даже такие, как структурное программирование или ООП. Только с высоты высокоуровневого языка кажется, что в условии if
нет ничего любопытного и оно лишено какого‑либо разнообразия. Но для компилятора это простор для самодеятельности! И в близких по духу ситуациях он может построить кардинально различающийся код.
В процессорной архитектуре x86 предусмотрен весьма «оригинальный» набор команд для перенаправления хода выполнения программного кода. «Оригинальный» не значит хороший или плохой, это значит, что он отличается от набора микропроцессоров других архитектур и производителей: ARM, MIPS, SPARC и так далее. Как ты знаешь, первый процессор этой серии создавался впопыхах для временной замены еще не готового iAPX-432, последний, в свою очередь, должен был уметь в многозадачность и управление памятью на аппаратном уровне. Чего в итоге не случилось. А x86 продолжил свое развитие. Поэтому сейчас, когда за годы эволюции процессоров серии x86 скопился набор инструкций, хакерам приходится разгребать весь этот хлам, дабы раскрутить порядок выполнения машинных инструкций.
Идентификация условных операторов
Существует два вида алгоритмов — безусловные и условные. Порядок действий безусловного алгоритма всегда постоянен и не зависит от входных данных. Например, a = b + c. Порядок действий условных алгоритмов, напротив, зависит от данных, поступающих «на вход». Например:
если c не равно нулю,
то: a = b/c;
иначе: вывести сообщение об ошибке
Обрати внимание на выделенные жирным шрифтом ключевые слова «если», «то» и «иначе», называемые операторами условия или условными операторами. Без них не обходится ни одна программа (вырожденные примеры наподобие «Hello, World!» не в счет). Условные операторы — сердце любого языка программирования. Поэтому чрезвычайно важно уметь их правильно определять.
В общем виде (не углубляясь в синтаксические подробности отдельных языков) оператор условия схематично изображается так:
IF (условие) THEN { оператор1; оператор2; } ELSE { операторa; операторb; }
Задача компилятора — преобразовать эту конструкцию в последовательность машинных команд, выполняющих оператор1, оператор2, если условие истинно, и операторa, операторb — если оно ложно. Однако микропроцессоры серии 80x86 поддерживают весьма скромный набор условных команд, ограниченный фактически одними условными переходами. Программистам, знакомым лишь с IBM PC, такое ограничение не покажется чем‑то неестественным, между тем существует масса процессоров, поддерживающих префикс условного выполнения инструкции. То есть вместо того, чтобы писать:
TEST ECX,ECX
JNZ xxx
MOV EAX,0x666
там поступают так:
TEST ECX,ECX
IFZ MOV EAX,0x666
IFZ
и есть префикс условного выполнения, разрешающий выполнение следующей команды только в том случае, если установлен флаг нуля. В этом смысле микропроцессоры 80x86 можно сравнить с ранними диалектами языка Basic, не разрешающими использовать в условных выражениях никакой другой оператор, кроме GOTO. Сравни:
Старый диалект Basic:
10 IF A=B THEN GOTO 30
20 GOTO 40
30 PRINT "A=B"
40 ... // Прочий код программы
Новый диалект Basic:
IF A=B THEN PRINT "A=B"
Если ты когда‑нибудь программировал на старых диалектах Basic, то, вероятно, помнишь, что гораздо выгоднее выполнять GOTO
, если условие ложно, а в противном случае продолжать нормальное выполнение программы. Как видишь, вопреки расхожему мнению, навыки программирования на Basic отнюдь не бесполезны, особенно в дизассемблировании программ.
Большинство компиляторов (даже не оптимизирующих) инвертируют истинность условия, транслируя конструкцию
IF (условие) THEN { оператор1; оператор2; }
в следующий псевдокод:
Следовательно, для восстановления исходного текста программы нам придется вновь инвертировать условие и «подцепить» блок операторов { оператор1; оператор2; } к ключевому слову THEN
. Иначе говоря, если откомпилированный код выглядит так:
10 IF A<>B THEN 30
20 PRINT "A=B"
30 ...// Прочий код программы
можно с уверенностью утверждать, что в исходном тексте присутствовали строки IF
. А если программист, наоборот, проверял переменные A и B на неравенство, то есть в коде присутствовала конструкция IF
? Все равно компилятор инвертирует истинность условия и сгенерирует следующий код:
10 IF A=B THEN 30
20 PRINT "A<>B"
30 ... // Прочий код программы
Конечно, встречаются и компиляторы, страдающие многословием. Их легко распознать по безусловному переходу, следующему сразу же после условного оператора:
В таком случае инвертировать условие не нужно. Впрочем, если это сделать, ничего страшного не произойдет, разве что код программы станет менее понятным, да и то не всегда.
Рассмотрим теперь, как транслируется полная конструкция
IF (условие) THEN { оператор1; оператор2; } ELSE { операторa; операторb; }.
Одни компиляторы поступают так:
А другие — так:
Разница между ними в том, что вторые инвертируют истинность условия, а первые — нет. Поэтому, не зная «нрава» компилятора, определить, как выглядел подлинный исходный текст программы, невозможно! Однако это не создает проблем, ибо условие всегда можно записать так, как это удобно. Допустим, не нравится тебе вот такая конструкция:
IF (c <> 0) THEN a = b / c ELSE PRINT "Ошибка!"
Пиши ее так:
IF (c == 0) THEN PRINT "Ошибка!" ELSE a = b / c
И никаких гвоздей!
Скачать:
Скриншоты:
Важно:
Все статьи и материал на сайте размещаются из свободных источников. Приносим свои глубочайшие извинения, если Ваша статья или материал была опубликована без Вашего на то согласия.
Напишите нам, и мы в срочном порядке примем меры.