Циклы в ассемблере: Ассемблер ARM64 | Циклы

Инструкция LOOP


Английский за 3 месяца

Хотим мы того или нет, но английский язык стал международным средством общения. В Европе он входит в школьную программу, причём на таком уровне, что после школы все дети умеют достаточно хорошо говорить на английском. Это надо просто принять как данность и использовать. Лишать себя возможности быть частью мирового сообщества, это, как минимум, недальновидно. Подробнее…

Инструкция LOOP в Ассемблере уменьшает значение в регистре СХ в реальном режиме или ECX в защищённом. Если после этого значение в СХ не равно нулю, то команда LOOP выполняет переход на МЕТКУ. Синтаксис:

LOOP МЕТКА

Состояние флагов не изменяется.

МЕТКА — это допустимый в Ассемблере идентификатор. О метках в Ассемблере я рассказывал здесь.

Алгоритм работы команды LOOP:

  • CX = CX — 1
  • Если CX не равен 0, то выполнить переход (продолжить цикл)
  • Иначе не выполнять переход (прервать цикл и продолжить выполнение программы)

То есть команда LOOP выполняется в два этапа. Сначала из регистра СХ вычитается единица и его значение сравнивается с нулём. Если регистр не равен нулю, то выполняется переход к указанной МЕТКЕ. Иначе переход не выполняется и управление передаётся команде, которая следует сразу после команды LOOP.

Как выполнить цикл в Ассемблере

Выполнение цикла в Ассемблере можно организовать с помощью нескольких команд. Одна из таких команд — это команда LOOP. Команда цикла в Ассемблере всегда уменьшает значение счётчика на единицу. Это значение находится в регистре СХ (или ECX).

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

Команда LOOP выполняет переход к метке во всех случаях, когда значение в регистре СХ не равно нулю. Чтобы организовать цикл с помощью этой команды, нам надо сначала в регистр СХ записать число итераций цикла (то есть сколько раз цикл должен быть выполнен), затем вставить в код метку, а затем написать команды, которые должны быть выполнены в цикле. А уже в конце списка этих команд записать команду LOOP.

Более понятно это будет в примере программы (см. ниже).

ПРИМЕЧАНИЕ
В качестве счётчика команда LOOP использует регистр CX в реальном режиме, и регистр ECX в защищённом режиме. Это не всегда удобно, если программу (или её часть) планируется использовать в обоих режимах. Поэтому в системе команд процессоров Интел предусмотрены две специальные команды — LOOPD и LOOPW, которые независимо от режима работы процессора в качестве счётчика используют регистры ECX и CX соответственно.

Пример программы:


  .model	tiny
  .code
  ORG 	100h
	
start:	
  MOV CX, 26        ; Цикл будет выполнен 26 раз
  MOV DL, 'A'       ; CL = 41h (ASCII-код) - первая буква
  MOV BX, 676h      ; Позиция первой буквы на экране
  MOV AX, 0B800h    ; Установить AX = B800h (память VGA)
  MOV DS, AX        ; Копировать значение из AX в DS	
  MOV DH, 01001110b ; CH = атрибуты цвета

abcde:
  MOV [BX], DX      ; Записать символ в видеопамять
  INC DL            ; Увеличить ASCII-код (для следующего символа)
  ADD BX, 2         ; Сместить координаты
  
LOOP
abcde ; Повторить цикл END start

Возможные ошибки

Начинающие довольно часто совершают одни и те же ошибки при организации циклов в Ассемблере. А именно — неправильно задают или обнуляют значение счётчика перед выполнение цикла.

При обнулении счётчика перед циклом при первой итерации цикла значение в регистре CX будет равно FFFFh (потому что команда LOOP отнимет от СХ единицу, а в СХ у нас был 0), и цикл в программе будет выполняться, соответственно 65536 раз.

Ещё один момент: диапазон адресов для передачи управления в команде LOOP ограничен в пределах -128…+127 байтов относительно адреса следующей команды. Если учесть, что в реальном режиме процессора средняя длина машинной команды равна 3 байта, то получается, что блок команд, выполняющихся в цикле, может состоять примерно из 42 команд. Если же в вашем цикле будет больше команд, то, например, MASM, выдаст сообщение об ошибке, которое будет выглядеть примерно так:

error A2075: jump destination too far : by 10 byte(s)

Здесь говорится, что местоположение перехода слишком далеко (примерно на 10 байт больше допустимого).

Ещё одна ошибка — это изменение значения регистра CX в теле цикла. В итоге команда LOOP будет работать неправильно. К тому же при этом можно попасть в бесконечный цикл. Пример:


  MOV CX, 2      ; Устанавливаем счётчик
top:
  INC CX
  LOOP top

Здесь в теле цикла увеличивается значение регистра СХ, поэтому он никогда не будет равен нулю, и, следовательно, цикл никогда не завершится.

А теперь о происхождении мнемоники LOOP. В общем то это не мнемоника, а слово. В переводе с английского оно означает “петля”, “виток”, “цикл”.


Подписаться на Дзен-канал

Вступить в группу «Основы программирования»

Подписаться на рассылки по программированию


Первые шаги в программирование

Главный вопрос начинающего программиста – с чего начать? Вроде бы есть желание, но иногда «не знаешь, как начать думать, чтобы до такого додуматься». У человека, который никогда не имел дело с информационными технологиями, даже простые вопросы могут вызвать большие трудности и отнять много времени на решение. Подробнее…


Организация циклов в Ассемблере.

Команды управления циклами. Организация циклов

Цикл, как известно, представляет собой важную алгоритмическую структуру, без использования которой не обходится, наверное, ни одна программа. Организовать циклическое выполнение некоторого участка программы можно, к примеру, используя команды условной передачи управления или команду безусловного перехода jmp. При такой организации цикла все операции по его организации выполняются “вручную”. Но, учитывая важность такого алгоритмического элемента, как цикл, разработчики микропроцессора ввели в систему команд группу из трех команд, облегчающую программирование циклов. Эти команды также используют регистр ecx/cx как счетчик цикла. Дадим краткую характеристику этим командам: 

loop метка_перехода (Loop) — повторить цикл. Команда позволяет организовать циклы, подобные циклам for в языках высокого уровня с автоматическим уменьшением счетчика цикла. Работа команды заключается в выполнении следующих действий:

  • декремента регистра ecx/cx;

  • сравнения регистра ecx/cx с нулем:

    • если (ecx/cx) > 0, то управление передается на метку перехода;

    • если (ecx/cx) = 0, то управление передается на следующую после loop команду.

loope/loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0) — повторить цикл, пока cx <> 0 или zf = 0. Команды loope и loopz — абсолютные синонимы, поэтому используйте ту команду, которая вам больше нравиться. Работа команд заключается в выполнении следующих действий:

  • декремента регистра ecx/cx;

  • сравнения регистра ecx/cx с нулем;

  • анализа состояния флага нуля zf:

    • если (ecx/cx) > 0 и zf = 1, управление передается на метку перехода;

    • если (ecx/cx) = 0 или zf = 0, управление передается на следующую после loop команду.

loopne/loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag=0) — повторить цикл пока cx <> 0 или zf = 1. Команды loopne и loopnz также абсолютные синонимы. Работа команд заключается в выполнении следующих действий:

  • декремента регистра ecx/cx;

  • сравнения регистра ecx/cx с нулем;

  • анализа состояния флага нуля zf:

    • если (ecx/cx) > 0 и zf = 0, управление передается на метку перехода;

    • если (ecx/cx)=0 или zf=1, управление передается на следующую после loop команду.

Команды loope/loopz и loopne/loopnz по принципу своей работы являются взаимообратными. Они расширяют действие команды

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

Недостаток команд организации цикла loop, loope/loopz и loopne/loopnz в том, что они реализуют только короткие переходы (от –128 до +127 байт). Для работы с длинными циклами придется использовать команды условного перехода и команду jmp, поэтому постарайтесь освоить оба способа организации циклов. 

  1. Режимы адресации операндов в командах Ассемблера. Косвенная адресация. Модификация адресов, и индексирование.

Косвенная адресация По аналогии с регистровыми и непосредственными операндами адрес операнда в памяти также можно не указывать непосредственно, а хранить в любом регистре. До 80386 для этого можно было использовать только BX, SI, DI и BP, но потом эти ограничения были сняты и адрес операнда разрешили считывать также и из EAX, EBX, ECX, EDX, ESI, EDI, EBP и ESP (но не из AX, CX, DX или SP напрямую — надо использовать EAX, ECX, EDX, ESP соответственно или предварительно скопировать смещение в BX, SI, DI или BP).

Например, следующая команда помещает в регистр AX слово из ячейки памяти, селектор сегмента которой находится в DS, а смещение — в BX:

mov ax,[bx]

Как и в случае прямой адресации, DS используется по умолчанию, но не во всех случаях: если смещение берут из регистров ESP, EBP или BP, то в качестве сегментного регистра используется SS. В реальном режиме можно свободно пользоваться всеми 32-битными регистрами, надо только следить, чтобы их содержимое не превышало границ 16-битного слова.

Модификация адресов

В ПК используется так называемая модификация адресов. Если в команде операнд берется из памяти, тогда сослаться на него можно указав некоторый адрес и некоторый регистр. В этом случае команда будет работать с так называе­мым исполнительным адресом, который вычисляется как сумма адреса, указанно­го в команде, и текущего значения указанного регистра. Именно из ячейки с та­ким адресом команда и будет брать свой операнд. Выгода от такого способа задания операнда заключается в том, что, меняя значение регистра, можно заста­вить одну и ту же команду работать с разными ячейками памяти, что, например, полезно при обработке массивов, когда одну и ту же команду надо применять к разным элементам массивов. Замена адреса, указанного в команде, на исполни­тельный адрес называется модификацией адреса, а используемый при этом ре­гистр называется модификатором. Во многих ЭВМ в качестве модификатора можно использовать любой из имеющихся регистров, но вот в ПК модификато­рами могут быть только регистры ВХ, ВР, SI и DI. В этом и заключается основ­ная специализация данных регистров. Отметим также, что в ПК модифицировать адрес можно не только по одному регистру, но и по двум сразу. Правда, в этом случае разрешено использовать не любую пару указанных модификаторов, а только такую, где один из регистров — это ВХ или ВР, а другой — это SI или DI.

7.7: Инструкции по управлению — Технические тексты LibreTexts

  1. Последнее обновление
  2. Сохранить как PDF
  • Идентификатор страницы
    55762
  • Управление программой относится к базовым структурам программирования, таким как операторы IF и циклы.

    Все управляющие структуры языка высокого уровня должны выполняться с ограниченными управляющими структурами языка ассемблера. Например, оператор IF-THEN-ELSE не существует на уровне языка ассемблера. Язык ассемблера предоставляет безусловный переход (или переход) и условный переход или оператор IF, который будет переходить к целевой метке или не переходить.

    Инструкции по управлению относятся к безусловному и условному переходу. Переход требуется для основных условных операторов (например, операторов IF) и циклов.

    Метки

    Метка программы является целью или местом для перехода к управляющим операторам. Например, начало цикла может быть отмечено меткой, такой как «loopStart». Код можно выполнить повторно, перейдя на метку.

    Обычно метка начинается с буквы, за которой следуют буквы, цифры или символы (не более «_»), заканчивающиеся двоеточием («:»). Метки можно начинать с небуквенных символов (например, цифр, «_», «$», «#», «@», «~» или «?»). Однако они обычно имеют особое значение и, как правило, не должны использоваться программистами. Этикетки в yasm чувствительны к регистру.

    Например,

      loopStart:
         последний:
      

    являются допустимыми метками. Метки программы могут быть определены только один раз. В следующих разделах описано, как используются метки.

    Безусловные инструкции управления

    Безусловная инструкция обеспечивает безусловный переход к определенному месту в программе, обозначенному меткой программы. Целевая метка должна быть определена ровно один раз и доступна и находится в пределах области действия исходной инструкции перехода.

    Инструкция безусловного перехода резюмируется следующим образом:

    Инструкция

    Пояснение

      jmp <метка>  

    Перейти к указанной метке.
    Примечание , метка должна быть определена ровно один раз.

    Примеры:

      jmp startLoop
    jmp, если выполнено
    джмп последний
      

    />Условное управление

    Инструкции

    Более полный список инструкций находится в Приложении B.

    Инструкции условного управления обеспечивают условный переход на основе сравнения. Это обеспечивает функциональность базового оператора IF.

    Для сравнения требуется два шага; инструкция сравнения и инструкция условного перехода. Инструкция условного перехода будет переходить или не переходить к предоставленной метке

    в зависимости от результата предыдущей операции сравнения. Команда сравнения сравнивает два операнда и сохраняет результаты сравнения в регистрах rFlag . Команда условного перехода будет действовать (переходить или не переходить) в зависимости от содержимого регистра rFlag . Это требует, чтобы за инструкцией сравнения сразу же следовала инструкция условного перехода. Если между сравнением и условным переходом помещаются другие инструкции, Регистр rFlag будет изменен, и условный переход может не отражать правильное условие.

    Общая форма инструкции сравнения:

      cmp ,  
     

    Где и не изменяются и должны быть одного размера. Любой из них, но не оба, может быть операндом памяти. Операнд не может быть немедленным, но операнд может быть непосредственным значением.

    Инструкции условного управления включают переход равный ( je ) и переход не равный ( jne ), которые работают одинаково как для подписанных, так и для беззнаковых данных.

    Подписанные инструкции условного контроля включают в себя базовый набор операций сравнения; прыжок меньше ( jl ), прыжок меньше или равно ( jle ), прыжок больше ( jg ) и прыжок больше или равен ( jge ).

    Беззнаковые инструкции условного управления включают в себя базовый набор операций сравнения; прыгать ниже чем ( jb ), прыжок ниже или равно ( jbe ), прыжок выше чем ( ja ) и прыжок выше или равно ( jae ).

    Общий вид подписанных условных инструкций вместе с пояснительным комментарием следующий:

    Page 110

      je <метка> ; если  == 
        jne <метка> ; если  != 
        
        jl <метка> ; подписано, если  < 
        jle <метка> ; подписано, если  <= 
        jg <метка> ; подписано, если  > 
        jge <метка> ; подписано, если  >= 
        
        jb <метка> ; без знака, если  < 
        jbe <метка> ; без знака, если  <= 
        да <метка> ; без знака, если  > 
        дже <метка> ; без знака, если  >=  
     

    Например, при наличии следующего псевдокода для подписанных данных:

      if (currNum > myMax)
               мойМакс = ТекущееЧисло;
      

    И, предполагая следующие декларации данных:

      currNum dq 0
         мойМакс дк 0 
     

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

      mov rax, qword [currNum]
         cmp rax, qword [myMax] ; если currNum <= myMax
         JLE неНовыйМакс ; пропустить установить новый максимум
         mov qword [myMax], rax
    неНовыйМакс: 
     

    Обратите внимание, что логика оператора IF была изменена на противоположную. Сравнение и условный переход обеспечивают функциональность перехода или отказа от перехода. Таким образом, если условие из исходного оператора IF ложно, код не должен выполняться. Таким образом, при значении false, чтобы пропустить выполнение, условный переход перейдет к целевой метке сразу после кода, который нужно пропустить (не выполнить). Хотя в этом примере всего одна строка, строк кода может быть много.

    Более сложный пример может быть следующим:

      if (x != 0) {
               ответ = х/у;
               errFlg = ЛОЖЬ;
         } еще {
               ответ = 0;
               errFlg = ИСТИНА;
         }
      

    Это базовое сравнение и условный переход не обеспечивают типичную структуру IF-ELSE. Он должен быть создан. Предположим, что переменные x и y являются двойными словами со знаком, которые будут установлены во время выполнения программы, и следующие объявления:

      ИСТИНА экв 1
         ЛОЖЬ экв.  0
         х дд 0
         г дд 0
         и дд 0
         errFlg БД ЛОЖЬ 
     

    Следующий код можно использовать для реализации приведенного выше оператора IF-ELSE.

      cmp двойное слово [x], 0 ; если оператор
         je doОстальное
         mov eax, двойное слово [x]
         компакт-диск
         idiv двойное слово [y]
         mov двойное слово [анс], eax
         байт перемещения [errFlg], ЛОЖЬ
         jmp skpElse
    сделатьЕще:
         mov двойное слово [ответ], 0
         байт перемещения [errFlg], ИСТИНА
    skpЕще: 
     

    В этом примере, поскольку данные были подписаны, требовалось знаковое деление ( idiv ) и соответствующее преобразование ( cdq в данном случае). Следует также отметить, что регистр edx был перезаписан, хотя явно не отображался. Если значение ранее было помещено в edx (или rdx ), оно было изменено.

    Диапазон

    Целевая метка называется коротким переходом. В частности, это означает, что целевая метка должна находиться в пределах 128 байт от инструкции условного перехода. Хотя это ограничение обычно не является проблемой, для очень больших циклов ассемблер может сгенерировать ошибку, относящуюся к «выходу за пределы диапазона». Безусловный прыжок ( jmp ) не ограничен в диапазоне. Если генерируется «прыжок за пределы диапазона», его можно устранить, обратив логику и используя безусловный переход для длинного перехода. Например, следующий код:

      cmp rcx, 0
         jne startOfLoop 
     

    может вызвать ошибку ассемблера «выход за пределы диапазона», если метка startOfLoop находится на большом расстоянии. Ошибку можно устранить следующим кодом:

      cmp rcx, 0
         je endOfLoop
         jmp startOfLoop
    конец цикла: 
     

    Который выполняет то же самое, используя безусловный переход для длинного перехода и добавляя условный переход к очень близкой метке.

    Инструкции условного перехода резюмируются следующим образом:

    Инструкция

    Пояснение

      cmp , 
      

    Сравните с .
    Результаты сохраняются в регистре rFlag . Примечание 1 , операнды не изменяются.
    Примечание 2 , оба операнда не могут быть памятью. Примечание 3 , операнд не может быть непосредственным.

    Примеры:

      см. ракс, 5
    cmp ecx, edx
    cmp топор, слово [wNum]
      
      je <метка>  

    На основании предыдущей инструкции сравнения перейти к <метка> , если == .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    я был равным
      
      jne <метка>  

    На основании предыдущей инструкции сравнения перейти к <метка> , если != .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jne wasNotEqual
      
      jl <метка>  

    Для подписанных данных на основе предыдущей инструкции сравнения перейти к <метка> , если < .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jl было меньше
      
      jle <метка>  

    Для данных со знаком, на основе предыдущей инструкции сравнения, перейти к <метка> , если .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jle былLessOrEqual
      
      мкг <метка>  

    Для подписанных данных на основе предыдущей инструкции сравнения перейдите к , если > .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jg было больше
      
      jge <метка>  

    Для подписанных данных на основе предыдущей инструкции сравнения перейти к <метка> если .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jge был больше или равен
      
      jb <метка>  

    Для данных без знака, на основе предыдущей инструкции сравнения, перейти к <метка> если < .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jb было меньше
      
      jbe <метка>  

    Для данных без знака, на основе предыдущей инструкции сравнения, перейти к <метка> если .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jbe былLessOrEqual
      
      и <метка>  

    Для данных без знака, на основе предыдущей инструкции сравнения, перейти к <метка> если > .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    ja wasGreater
      
      jae <метка>  

    Для данных без знака, на основе предыдущей инструкции сравнения, перейти к <метка> если .
    Метка должна быть определена ровно один раз.

    Примеры:

      см. ракс, 5
    jae был больше или равен
      

    Более полный список инструкций находится в Приложении B.

    Итерация

    Описанные основные инструкции управления предоставляют средства для итерации или цикла.

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

    Например, при следующих объявлениях:

      lpCnt dq 15
        сумма dq 0 
     

    Следующий код суммирует нечетные целые числа от 1 до 30:

      mov rcx, qword [lpCnt] ; счетчик циклов
        мов ракс, 1 ; счетчик нечетных целых чисел
    суммаЦикл:
        добавить qword [сумма], rax ; сумма текущего нечетного целого числа
        добавить ракс, 2 ; установить следующее нечетное целое число
        dec rcx ; счетчик циклов уменьшения
        cmp rcx, 0
        джне суммапетля 
     

    Это лишь один из многих способов выполнения задачи суммирования нечетных целых чисел. В этом примере rcx использовалось в качестве счетчика циклов, а rax использовалось для текущего нечетного целого числа (соответствующим образом инициализированного до 1 и увеличенного на 2).

    Процесс, показанный с использованием rcx в качестве счетчика, полезен при циклическом выполнении заданное количество раз. Существует специальная инструкция loop , обеспечивающая поддержку циклов.

    Общий формат следующий:

      loop  

    Который будет выполнять декремент регистра rcx , сравнение с 0 и переход к указанной

    метке, если rcx 0. Метка должна быть определена ровно один раз.
    Таким образом, инструкция цикла обеспечивает ту же функциональность, что и три строки кода

    из предыдущего примера программы. Следующие наборы кодов эквивалентны:

      Набор кодов 1 Набор кодов 2
        петля <метка> dec rcx
                                 cmp rcx, 0
                                 jne <метка>  

    Например, предыдущую программу можно записать так:

      mov rcx, qword [maxN] ; счетчик циклов
        мов ракс, 1 ; счетчик нечетных целых чисел
    суммаЦикл:
        добавить qword [сумма], rax ; сумма текущего нечетного целого числа
        добавить ракс, 2 ; установить следующее нечетное целое число
        сумма цикловLoop 
     

    Оба примера кода дают один и тот же результат одним и тем же способом.

    Поскольку регистр rcx уменьшается, а затем проверяется, забыв установить rcx может привести к зацикливанию неизвестное количество раз. Это может вызвать ошибку во время выполнения цикла, что может ввести в заблуждение при отладке.

    Инструкция loop может быть полезна при кодировании, но она ограничена регистром rcx и обратным отсчетом. Если требуются вложенные циклы, использование инструкции цикла как для внутреннего, так и для внешнего цикла может вызвать конфликт, если не будут предприняты дополнительные действия (например, сохранение/восстановление 9).0034 rcx регистр, необходимый для внутреннего цикла).

    Хотя в некоторых примерах программирования в этом тексте используется инструкция цикла, это не обязательно.

    Инструкция цикла резюмируется следующим образом:

    Инструкция

    Пояснение

      петля <метка>  

    Уменьшить rcx регистр и перейти к <метка> , если rcx равно 0.
    Примечание , метка должна быть определена ровно один раз.

    Примеры:

      начало циклаЦикл
    цикл ifDone
    сумма циклаЦикл
      

    Более полный список инструкций находится в Приложении B.


    7.7: Инструкции по управлению распространяются по не объявленной лицензии и были созданы, изменены и/или курированы LibreTexts.

    1. Наверх
      • Была ли эта статья полезной?
      1. Тип изделия
        Раздел или Страница
      2. Теги
          На этой странице нет тегов.

      Использование условий и циклов в языке ассемблера.

      Условия и цикл с кодом на ассемблере

      Условный запуск на языке ассемблера сопровождается множеством инструкций по созданию циклов и ответвлений. Сначала мы обсуждаем здесь условия в сборке, а затем циклы в сборке.

      Условия в ассемблере

      Условное выполнение на ассемблере осуществляется несколькими инструкциями цикла и ветвления. Эти инструкции могут изменить поток управления в программе. Условное выполнение наблюдается в двух сценариях:

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

      Это выполняется командой JMP. Условное выполнение часто включает в себя передачу управления на адрес инструкции, которая не следует за выполняемой в данный момент инструкцией. Передача управления может быть прямой для выполнения нового набора инструкций или обратной для повторного выполнения тех же шагов.

       2. Условный переход

      Выполняется набором инструкций перехода j<условие> в зависимости от условия. Условные инструкции передают управление, прерывая последовательный поток, и делают это, изменяя значение смещения в IP.

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

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

      Синтаксис

      Инструкция JMP предоставляет имя метки, по которой поток управления передается немедленно. Синтаксис инструкции JMP:

      Пример

       MOV  AX, 00    ; Инициализация AX в 0
      
      MOV BX, 00    ; Инициализация BX в 0
      
      MOV CX, 01    ; Инициализация CX до 1
      
      Л20:
      
      ДОБАВИТЬ AX, 01    ; Приращение AX
      
      ДОБАВИТЬ BX, AX    ; Добавить AX к BX
      
      ШЛ СХ, 1     ; сдвиг CX влево, это, в свою очередь, удваивает значение CX
      
      JMP  L20       ; повторяет утверждения 

       

      Условный переход

      Если какое-то заданное условие выполняется при условном переходе, поток управления передается целевой инструкции. Существует множество инструкций условного перехода в зависимости от условий и данных. Синтаксис набора инструкций J<условие>.

      Пример:

       CMP      AL, BL
      
      JE       РАВНО
      
      CMP      AL, BH
      
      JE       РАВНО
      
      CMP      AL, CL
      
      JE       РАВНО
      
      НЕ РАВНО: ...
      
      РАВНО: ... 

      Пример

      Следующая программа отображает наибольшую из трех переменных. Переменные являются двузначными переменными. Три переменные num1, num2 и num3 имеют значения 47, 22 и 31 соответственно:

       section .text
      
      global _start         ; необходимо объявить для использования gcc
      
      _start:                    ;указать точку входа компоновщика
      
      mov   ecx, [num1]
      
      cmp   ecx, [num2]
      
      jg    check_ Third_num
      mov   ecx, [число2]
      
      чек_третий_номер:
      
      cmp   ecx, [num3]
      
      jg    _exit
      
      mov   ecx, [num3]
      
      _Выход:
      
      mov   [самый большой], ecx
      
      mov   ecx,msg
      
      mov   edx, лен
      
      mov   ebx,1     ;дескриптор файла (стандартный вывод)
      
      mov   eax,4      ;номер системного вызова (sys_write)
      
      int   0x80           ;вызов ядра
      
      mov   ecx,самый большой
      
      мов   edx, 2
      
      mov   ebx,1     ;дескриптор файла (стандартный вывод)
      
      mov   eax,4      ;номер системного вызова (sys_write)
      
      int   0x80           ;вызов ядра
      
      mov  eax, 1
      
      интервал 80 ч. 
      
      раздел .данные
      
      msg db "Самая большая цифра: ", 0xA,0xD
      
      len equ $- msg
      
      число1 дд '47'
      
      число2 дд '22'
      
      число3 дд '31'
      
      сегмент .bss
      
      самый большой член 2 

       

      ВЫВОД:

      Наибольшая цифра:

      47

      Использование циклов в ассемблере

      Команда JMP может использоваться для реализации циклов. Например, следующий фрагмент кода можно использовать для выполнения тела цикла 10 раз.

       МОВ     КЛ, 10
      
      L1:
      
      
      
      ДЕК        КЛ
      
      JNZ         L1 

      Однако набор инструкций процессора включает группу инструкций цикла для реализации итерации. Базовая инструкция LOOP имеет следующий синтаксис:

      LOOP     метка

      Где метка — это целевая метка, которая идентифицирует целевую инструкцию, как в инструкциях перехода. Инструкция LOOP предполагает, что регистр ECX содержит количество циклов. Когда инструкция цикла выполняется, регистр ECX уменьшается, и управление переходит к целевой метке до тех пор, пока значение регистра ECX, т. е. счетчик, не достигнет нулевого значения. Приведенный выше фрагмент кода можно записать так:

       mov ECX,10
      
      л1:
      
      <тело цикла>
      
      петля л1 

      Пример

      Следующая программа выводит на экран числа от 1 до 9:

       section .text
      
      global _start        ; необходимо объявить для использования gcc
      
      _start:                   ;указать точку входа компоновщика
      
      мов экх, 10
      перемещение ах, '1'
      
      л1:
      
      mov [число], eax
      
      мов акс, 4
      
      мов ебкс, 1
      
      нажать ecx
      
      mov ecx, число
      
      мов эдкс, 1
      
      интервал 0x80
      
      mov eax, [число]
      
      вспомогательный акс, '0'
      
      вкл.
      
      добавить eax, '0'
      
      поп экс
      
      петля л1
      
      mov eax,1             ;системный номер вызова (sys_exit)
      
      int 0x80              ;вызвать ядро
      
      раздел .bss
      
      число соотв. 1 

       

      ВЫХОД

      123456789:

      Чтение | 0 Комментариев

      ОТРЫВОК ДЛЯ ЧТЕНИЯ 1: Тылацин Q1. carnivorous ключевые слова: выглядело так, как будто собака съела ряд полосок, диета съела целиком 1 . …………………………. ………. диета (2-й абзац 3-я и 4-я строчка) 1-й и 2-й абзац, 1-й абзац,подобие…

      Чтение | 0 комментариев

      ОТРЫВОК 1 Q1 (Неверно) (Многие мадагаскарские леса уничтожены нападениями насекомых.) Леса Мадагаскара превращаются в сельскохозяйственные угодья со скоростью один процент каждый год. Большая часть этих разрушений вызвана выращиванием основных культур страны…

      Чтение | 0 Комментариев

      Здесь мы обсудим плюсы и минусы всех вопросов прохождения с пошаговым решением, включая Советы и Стратегии. Reading Passage 1 – Roman Tunnels IELTS Cambridge 16, Test 4, Модуль академического чтения, Reading Passage 1 Вопросы 1-6. Подпишите схемы…

      Чтение | 0 комментариев

      Отрывок для чтения 1: Римское судостроение и навигация, Решение с ключом ответа , Отрывок для чтения 1: Римское кораблестроение и навигация IELTS Cambridge 16, Тест 3, Модуль академического чтения Cambridge IELTS 16, Тест 3: Отрывок для чтения 1 – Римское кораблестроение и .

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

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

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