Оператор условного перехода: Оператор условного перехода — Информатика, информационные технологии

Содержание

Операторы условного и безусловного перехода

Операторы условного и безусловного перехода.

 

Условный оператор (полная и сокращенная форма)

 

Форма организации действий, при которой в зависимости от выполнения некоторого условия совершается одна или другая последовательность действий, называется ветвлением. Для организации разветвления вычислительного процесса предназначен оператор условного перехода.

 

 

 

 

 

 

 

 

 

                               полное ветвление                                            не полное ветвление

 

Формат оператора:

 

IF  <Условие> THEN <N1 или оператор 1>

ELSE  < N2 или оператор 2>

 

Если условие, указанное в операторе выполняется, то управление передается строке с номером N1 или оператору 1, иначе — строке с номером N2 или оператору 2   — полная форма.

 

IF  <Условие> THEN <N1 или оператор 1>   — сокращенная  форма.

 

Если конструкция ELSE  отсутствует и условие, указанное в операторе IF не выполняется, то управление передается следующей за командой строке.

 

 

В Бейсике используются следующие знаки отношения между величинами:  =, <>, >, <, >=, <=

 

Оператор безусловного перехода.

 

Формат оператора:   GOTO N, где N – метка строки.

 

Множественный выбор (SELECT CASE)

 

SELECT CASE арифметическое или символьное выражение 

CASE условие 1

блок команд 1

…………….

[CASE ELSE

блок команд]

END SELECT

 

В поле операндов каждого оператора CASE надо указать условие в одном из трёх ФОРМАТОВ:

1.       CASE константа 1, константа 2, …

2.      CASE IS знак отношения константа

3.      CASE константа 1 ТО константа 2

В конструкции сначала вычисляется значение выражения, записанного в SELECT CASE. Далее проверяется, удовлетворят ли это значение одному из указанных  в CASE условий, если удовлетворяет, то выполняется блок команд, следующий за данным CASE.

 

Примеры.

 

Задача№1. Составьте алгоритм попадания точки с координатами (X,Y) в заштрихованную область.

CLS

INPUT  “ Введи X, Y ”, X, Y

 

IF Y > 3-X THEN PRINT ”точка 

   лежит в заштрихованной области ”

ELSE PRINT ” точка  не лежит в

           заштрихованной области  ”

END

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Задача 1. 2 + 7*X-11

PRINT “ Y=“, Y

END

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Электронный справочник по ИНФОРМАТИКЕ (Автор Панов В.А.)


Оператор условного перехода IF

Это управляющий оператор, осуществляющий условное ветвление по результатам проверки заложенного условия. Выражение в условии может принимать истинное или ложное значение.

Оператор можно применять в различных видах:

  1. неполном;
  2. полном;
  3. структурном.

Для более быстрого осваивания оператора IF рекомендуется повторить тему «Разветвляющиеся алгоритмы», вспомнить и еще раз разобрать условные конструкции в блок-схемах.

Этот оператор является управляющим оператором условного перехода (направление решения зависит от выполнения некоторого условия).

 

Формат неполного оператора:

IF (условие) THEN (операторы)

— если условие выполняется, тогда выполняются (операторы) после THEN, а затем работает оператор, следующий за IF;

— если условие не выполняется, тогда сразу срабатывает оператор, следующий за IF.

Логика оператора представлена на схеме:

Условие может быть сложным:

A < 1 OR A > 3 — А меньше 1 или А больше 3

B >-1 AND C < 2 – В больше -1 и С меньше 2

Задача-1.

С клавиатуры вводится число А, не равное нулю. Определить, положительное или отрицательное оно.

 

Формат полного оператора:

IF (условие) THEN (операторы_1) ELSE (операторы_2)

— если условие выполняется, тогда выполняются (операторы_1) после THEN, а затем работает оператор, следующий за IF;

— если условие не выполняется, тогда выполняются (операторы_2) после ELSE, а затем работает оператор, следующий за IF.

Логика оператора представлена на схеме:

Рассмотрим решение Задачи-1 с помощью полного оператора IF:

 

Структурный оператор IF

При блочной форме, QuickBASIC тестирует первое логическое выражение. Если оно «истина», выполняются операторы блока

THEN. Если первое выражение «ложь», оценивается каждое условие ELSEIF. При выполнении такого условия выполняются операторы данного блока. Если ни одно из условий ELSEIF не выполнено (все = «ложь»), выполняются операторы блока ELSE.

Блоки ELSE и ELSEIF могут отсутствовать. В блочную структуру IF можно вставить любое количество условий ELSEIF. Каждый из блоков может также содержать вложенные блочные структуры IF.

Операторы IF, ELSE, ELSEIF и END IF должны быть первыми операторами в строке. Блок должен заканчиваться оператором END IF.

Программы, написанные с использованием блочной формы легче читаются и отлаживаются.

При проверке сложных условий можно использовать и более современную конструкцию
SELECT… END SELECT.

Пример использования блочной формы IF.

..THEN…ELSE:

Задача-2. Вводится число от 0 до 1000. Определить количество цифр в нем.

 

Сборка

— как работает инструкция условного перехода с операндом SUB

спросил

Изменено 9 лет, 1 месяц назад

Просмотрено 4к раз

В данный момент я изучаю язык ассемблера, и в книге по ассемблеру Кипа Ирвина он рассказывает об инструкциях условного перехода и приводит следующий пример

 Пример 2:
мов бх, 1234ч
сабвуфер, 1234 ч
jne L5 ; прыжок не сделан
je L1 ; прыжок сделан
Пример 3:
мов сх,0FFFFh
вкл сх
jcxz L2 ; прыжок сделан
 

Может кто-нибудь объяснить мне, как работает «je L1» в примере 2. Вам не нужно где-то использовать команду cmp.

Что конкретно заставило вас подпрыгнуть, так как в этот момент bx=0;

Кроме того, почему в примере 3 был сделан переход. Я думал, что вы увеличиваете cx, однако jcxz проверит, если cx=0?

Любая помощь будет принята с благодарностью.

  • сборка
  • x86
  • masm
  • masm32

Нет, вам не нужно нигде использовать команду cmp . Многие инструкции влияют на флаги (или их подмножество).

sub особенно «хорош» для этой цели, потому что он влияет на флаги точно так же, как cmp (единственное различие между sub и cmp заключается в том, что sub записывает результат вычитание до адресата, тогда как cmp нет).

Помните, что je на самом деле просто синоним jz

, он не заботится о равенстве в любой форме, он просто смотрит на флаг Z. 1234h минус сам по себе, очевидно, равен нулю, поэтому следует установить флаг Z.

Во втором примере jcxz выполняет переход, если cx = 0 , что имеет место. После приращения cx оно будет равно нулю, потому что раньше было -1.

Поскольку битовый флаг, установленный при сравнении (в данном случае вас интересуют только ZF ) не очищен.

Кстати, вы должны использовать CMP , а не SUB .

«Условие» основано на флагах, обычно флаге переноса, нулевом флаге, отрицательном флаге и флаге переполнения. но не все архитектуры процессоров делают это одинаково, хотя большинство из них используют эти четыре флага.

Эти флаги выходят из «alu», и набор инструкций определяет, на какой флаг влияет или не влияет каждая из инструкций. Таким образом, вы должны просмотреть документацию по каждой инструкции, понять, какие флаги и как затронуты, а затем понять, помогает ли это вам или нет.

Вычитание или сравнение (разница обычно в том, что подпрограмма изменяет результирующий регистр или память, тогда как cmp делает все то же самое, что и вычитание, за исключением того, что она не изменяет место назначения) весьма полезна, потому что с помощью одного вычитания вы можете определить, что больше или равно или меньше (и комбинации меньше или равно, больше или равно).

Для случая je или jump, если они равны. Вычитание приведет к нулю или нет, если вы вычитаете a из b, а b и a имеют одно и то же значение, результат равен нулю. если результат равен нулю, то флаг z установлен, иначе флаг z не установлен. Таким образом, если сравнение привело к тому, что вещи равны, что совпадает с установленным флагом z, поэтому прыжок, если равен, также известен как прыжок, если ноль, прыжок, если результат был равен нулю, что совпадает с прыжком, если установлен нулевой флаг. Jne — это переход, если не равен, или переход, если нулевой флаг не установлен (иногда вы увидите jnz в зависимости от набора инструкций и синтаксиса). В вашем случае вы вычли 1234 из себя, результат был равен нулю, флаг z установлен, jne не влияет на флаги, он говорит, что переходит, если бит z равен нулю, или продолжает идти, поэтому он продолжал идти, тогда je говорит, что скачок, если флаг z установлено, что это было, поэтому он прыгнул…

Зарегистрируйтесь или войдите в систему

Зарегистрируйтесь с помощью Google

Зарегистрироваться через Facebook

Зарегистрируйтесь, используя электронную почту и пароль

Опубликовать как гость

Электронная почта

Требуется, но никогда не отображается

Опубликовать как гость

Электронная почта

Требуется, но не отображается

8086 условное кодирование перехода

8086 условное кодирование перехода

Вернуться на главную

  • I. Тип условных переходов
    • а. Список существующих прыжков
    • б. Класс эквивалентности
  • II. Кодирование инструкций
    • а. Пункт назначения прыжка
    • б. Условный прыжок
    • в. Как компоновщик выбирает длинный или короткий переход
    • д. Безусловные переходы
  • III. Компилятор онлайн-прыжков
  • IV. Углубленное изучение машинного кода
  • V. Онлайн-калькулятор прыжков

I. Тип условных переходов

а. Список существующих прыжков

0141
Код операции Описание Флаги ЦП
JA Выше CF = 0 и ZF = 0 5 JA8 9014 0150 Выше или равно CF = 0
JB Сильфон CF
JBE Сильфон или аналогичный CF или ZF
JC Carry 1 JE Равенство ZF
JG Большее (s) ZF = 0 и 05 JGE = 9 11181 Большее из равного (s) SF = OF
JL Меньше (s) SF ≠ OF
JLE Меньше равных (2) 0 ZF или SF ≠ OF
JNA Не выше CF или ZF
JNAE Не выше и не равно CF
JNB Не ниже CF = 0 JBE Ни ниже, ни равно CF = 0 и ZF = 0
JNC Не несет CF = 0
JNE Не равно ZF = 0
JN 90 0 Не меньше и не равно Отрицательный JP8 10154 0150 Нулевой
Не больше JNG 0151 ZF или SF ≠ OF
JNGE Не больше и не равно SF ≠ OF
JNL Не менее SF = OF
ZF = 0 и SF = OF
JNO Без переполнения OF = 0
JNP Без четности PF = 0
СФ = 0
ДНЗ Не ноль ZF = 0
JO Переполнение (s) OF
Четность PF
JPE Четность PF
JPO Непаритет PF = 0
JS Отрицательный (s) SF ZF

(с) подписанный режим

Два перехода не включены в предыдущий список: переходы JCXZ и JECXZ , которые не зависят от ФЛАГА ЦП но находятся в регистре CX (16 бит) или ECX (32 бита).

Инструкция безусловного перехода JMP .

б. Класс эквивалентности

Во-первых, взглянув на массив выше, мы видим, что несколько прыжков имеют одинаковые условия флага и получат одинаковый код операции.

  • JB ≡ JC ≡ JNAE
  • JAE ≡ JNB ≡ JNC
  • JE ≡ JZ
  • JNE ≡ JNZ
  • JBE ≡ ЮНА
  • JA ≡ JNBE
  • JP ≡ JPE
  • JNP ≡ JPO
  • JL ≡ JNGE
  • JGE ≡ JNL
  • JLE ≡ JNG
  • JG ≡ JNLE

Вот почему инструкция JE эквивалентна JZ. Также есть одиночные прыжки:

  • ДЖО
  • JNO
  • JS
  • JNS

Если посчитать количество прыжков, получится 16 разных случаев. Число 16 — это 2 4 или одна шестнадцатеричная цифра или также половина байта.
Затем Intel выделила 4 бита (полубайт) в коде операции для определения типа перехода.

Это значение, определяющее тип перехода, является частью кода операции. Обратите внимание на это значение $jump_type

JBJB JA JN 41
$jump_type Прыжки
0 JO
1 JNO
2 48
3 JAE JNB JNC
4 JE JZ
5 JNE JNZ
6 JBE JNA
7 11 154 8 JS
9 JNS
A JP JPE
B JNP JPO
C JL 5 JNGE 9014 8 1 9050 JL 5 JNGE 9014 150 D ДЖГЭ ДЖНЛ
Е ДЖЛЕ ДЖНГ
Ф ДЖГ ДЖНЛЕ

II. Код инструкции

а. Пункт назначения прыжка

Программатор использует определенные метки (блоки инструкций, номер строки, именованную метку и т. д.), но машинный код использует адреса памяти. Задача компоновщика состоит в том, чтобы вычислить и вставить эти адреса после этапа компиляции, чтобы сделать машинный код работоспособным.

Условные переходы используют относительные адреса, переходы выполняются из текущей инструкции, а расстояния определяются в байтах. Это относительное значение адреса отмечено $bytes_count

Важное примечание: адрес вычисляется с конца инструкции.

Фактически выполненный условный переход аналогичен «добавить eip, $bytes_count + инструкция_size»

$bytes_count может быть положительным или отрицательным, процессор может переходить вперед или назад. Значение может храниться в одном байте или в одном слове (2 или 4 байта).
Компоновщик делает этот выбор во время сборки: если $bytes_count слишком велик для хранения в одном байте, тогда компоновщик использует длинный переход.

б. Условный прыжок

Машинный код состоит из кода операции и, возможно, нескольких дополнительных байтов. Условный переход составляется так:

код операции
$jump_type
$bytes_count
  • код операции — это первый байт(ы) инструкции, которые должны быть распознаны ЦП.
  • $jump_type (часть кода операции) указывает тип условия (см. соответствующий массив).
  • $bytes_count используется для определения места перехода.

Машинный код короткого условного перехода: 7x yy; для длинного условного перехода код операции — 0F 8x yy yy yy yy.

Давайте посмотрим пример (с использованием w32dasm):

:00401000 7410 je 00401012 […] * Ссылка на (U)условный или (C)условный переход по адресу: |:00401000(К) | :00401012 40 нажатий

Машинный код 7410:

  1. 7 -> первая часть кода операции (короткий переход)
    $jump_type = 4 -> JE / JZ (w32dasm печатает JE)
  2. $bytes_count = 10 -> 16 байт

Переход программы с 00401000 на 00401012:
Имеем eip = 00401000
добавляем размер инструкции (2 байта) + $bytes_count (значение 0x10): 2 + 0x10 = 0x12
После инструкции перехода мы получили: eip = 00401012

Когда это длинный переход, $bytes_count сохраняется в 2 или 4 байтах в зависимости от типа программы:

  • Если это 16-битная программа, то все длинные переходы имеют $bytes_count, хранящийся в 2 байтах
  • Если это 32-битная программа, то все длинные переходы имеют $bytes_count, хранящийся в 4 байтах.

В отличие от Motorola, Intel меняет порядок байтов при кодировании инструкций. Такой способ упорядочения называется прямым порядком байтов.

Давайте посмотрим на пример прыжка в длину:

:00401000 0F8500010000 jne 00401106 […] * Ссылка на (U)условный или (C)условный переход по адресу: |:00401000(К) | :00401106 40 нажатий

Машинный код 0F8500100000:

  1. 0F8 -> первая часть кода операции (длинный переход)
    $jump_type = 5 -> JNE / JNZ
  2. $bytes_count равен «00010000»

Чтобы получить значение $bytes_count, мы переворачиваем каждый байт (каждую пару шестнадцатеричных цифр):
00010000 равно 00 01 00 00 и становится 00 00 01 00.
$bytes_count = 0x100

Переход идет на 0x106 байт вперед в памяти ($bytes_count + размер инструкции).

с. Как компоновщик выбирает длинный или короткий переход

Чтобы узнать из скольких байт компоновщик должен использовать длинный переход (вместо короткого), мы должны знать, каков максимальный ход короткого перехода.

Размер инструкции всегда 2 байта (в 16- или 32-битной программе), а $bytes_count хранится в одном байте (8 бит).
$bytes_count — это число со знаком, затем у нас есть бит знака, а остальные 7 бит используются для значения.

2 7 = 128 , $bytes_count изменится от -128 до +127 (0 здесь положительное значение).
Если мы добавим размер инструкции, реальный диапазон будет от -126 до 129.

Это предел, из которого компоновщик может изменить тип перехода: [-126; 129]

д. Безусловные переходы

С инструкцией JMP у нас есть гораздо больше возможностей:
  1. относительный переход, короткие и длинные переходы, такие как условные переходы
  2. скачки абсолютного адреса
  3. переход относительно значения регистра
  4. переход относительно значения памяти

Давайте поговорим о самых распространенных и интересных прыжках, коротком и длинном относительных прыжках:
Эти переходы работают как условные переходы, меняется только заголовок кода операции. Для коротких переходов используется заголовок EB, для длинных переходов используется код операции E9..

Пример короткого прыжка:

:00401000 EB10 jmp 00401012 […] * Ссылка на (U)условный или (C)условный переход по адресу: |:00401000(К) | :00401012 40 нажатий

Длинный переход 16-битной программы:

:00401000 E jmp 00401103 […] * Ссылка на (U)условный или (C)условный переход по адресу: |:00401000(К) | :00401103 40 нажатий

Длинный переход 32-битной программы:

:00401000 E0000 jmp 00401105 […] * Ссылка на (U)условный или (C)условный переход по адресу: |:00401000(К) | :00401105 40 нажатий

Изменить короткий условный переход на безусловный очень просто: просто замените первый байт 7x на EB

Если вы обрабатываете длинный условный переход, это немного сложнее:

  1. два кода операции не имеют одинакового размера
  2. помните: $bytes_count вычисляется до конца инструкции

В этом случае мы перезаписываем инструкцией NOP первый байт кода операции условного длинного перехода и замените второй байт кода операции инструкции длинным кодом операции JMP.
Длинный условный переход становится двумя инструкциями: NOP и JMP.

NOP — это специальная инструкция, используемая для заполнения, она ничего не делает и занимает всего один байт в памяти и один цикл процессора. Код операции NOP равен 9.0.

Например, если я хочу заставить этот условный JNS всегда прыгать

:00401000 0F80000 jns 00401106

Предложу как самую эффективную модификацию вот эту

:00401000 90 нет :00401001 E0000 jmp 00401106

III. Компилятор онлайн-прыжков

Я сделал этот небольшой компилятор, чтобы помочь вам понять. Он поддерживает только инструкции перехода и предназначен только для 32-битных программ.

: ЭББЕ

IV. Углубленное изучение машинного кода

а. Как преобразовать машинный код

Просто посмотрите снова на предыдущую таблицу:

01 JNO1 21 7
$jump_type Прыжки
0 JO
1
JB JC JNAE
3 JAE JNB JNC
4 JE JZ
5 JNE JNZ
6 JBE JNA1
JA JNBE
8 JS
9 JNS
A JP JPE
B JNP JPO
C 9 014 JNGE D JGE JNL
E JLE JNG
F JG JNLE

Если вы посмотрите внимательно, инженеры Intel очень хорошо упорядочили список условных переходов:
Они приписали значение $jump_type одному условию перехода и зарезервировали следующее значение для противоположного условия перехода.

Вы можете проверить с помощью первой таблицы этого документа (используя флаги ЦП), что:

  • JO (0) — прыжок, противоположный JNO (1)
  • JNO (1) — прыжок, противоположный JO (0)
  • […]
  • JNA (6) — обратный прыжок JNA (7)
  • JA (7) является обратным прыжком 7A (6)
  • […]
  • JLE (E) xx — прыжок, противоположный JG (F)
  • JG (F) — прыжок, противоположный JLE (E)

По этому поводу не так сложно найти алгоритм обратного условного перехода:

Двоичная система с основанием 2, поэтому четность числа (которая является операцией по модулю 2) получается только из последней цифры в двоичной системе, последнего бита.

8 Алгоритм работает только последний бит:

Затем изменение последнего бита $jump_type инвертирует условие перехода.

Оставить комментарий

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

© 2019 Штирлиц Сеть печатных салонов в Перми

Цифровая печать, цветное и черно-белое копирование документов, сканирование документов, ризография в Перми.

Четность Последний бит
Четный 0
Нечетный 1