Tooprogram.ru

Компьютерный справочник
0 просмотров
Рейтинг статьи
1 звезда2 звезды3 звезды4 звезды5 звезд
Загрузка...

Команда nop ассемблер

Команда NOP

Что такое JavaScript

Если вы интересуетесь программированием вообще, и сайтостроением в частности, то вы наверняка слышали слово JavaScript. И, если вы до сих пор не узнали толком, что же это такое, то пришло время сделать это. Подробнее.

Лирическое вступление

Недавно один из подписчиков моего канала просто завалил мои видео по ассемблеру гневными комментариями. Ну всё то ему не нравится: и звук плохой, и о своём сайте то я говорю слишком много, то видео слишком короткое, то слишком длинное. И моя манера говорить ему тоже не нравится. И даже видео в плейлисте отсортированы не так, как ему хочется. Ну блин всё не так.

Несколько раз он написал, что я плохой учитель и он уходит к другому (ну прям история неразделённой любви))).

Что тут сказать — всегда найдутся люди, которые критикуют всех и вся, и обливают дерьмом людей с удовольствием и даже с садистским наслаждением. Такие люди сами обычно мало что умеют. Но критиковать других очень любят.

Я обычно не обращаю на подобные вещи внимания. Но в этот раз обратил. Дело в том, что одно замечание этого товарища было всё-таки правильным. Далее скажу, какое, но сначала расставлю точки над i. Итак:

  1. Я не учитель. Я просто человек, который делится опытом и даёт советы. Нужен кому этот опыт — берите. Не нужен — идите мимо.
  2. Это мой канал и мои правила. Я не собираюсь ни под кого подстраиваться. Я буду делать видео так, как считаю нужным и тогда, когда считаю нужным.
  3. Я делаю это для себя. Потому что мне это нравится. Если бы мне это не нравилось, я бы не тратил на это время. Если это нравится кому-то ещё — хорошо. Всегда приятно, когда твоя работа кому-то интересна. Ну а если нет, то решение всё тоже — просто отписывайтесь.

А теперь о справедливом замечании. Поскольку на своём канале я в основном говорю о программировании, то я часто употребляю слово “синтаксис”. И так уж сложилось исторически, что я привык произносить его так:

синтАксис

то есть с ударением на втором слоге. На самом деле правильно говорить так:

сИнтаксис

то есть с ударением на первом слоге.

Ну что же, ошибку я признаю, и теперь буду стараться говорить правильно.

А теперь об инструкции

Команда NOP в Ассемблере ничего не делает. Синтаксис:

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

NOP — это однобайтовая команда, которая ничего не выполняет, а только занимает место и время. Машинный код команды NOP фактически соответствует команде

о которой я ещё не рассказывал, но если кратко, то она меняет местами два операнда.

Зачем нужна команда NOP

Возникает закономерный вопрос — для чего нужна команда NOP, которая ничего не делает, а только занимает место в программе и отнимает время у процессора?

И, тем не менее, такая команда есть практически во всех ассемблерах, включая ассемблеры для микроконтроллеров.

Эта команда, в основном, используется для выполнения небольшой задержки в программе. Если говорить о микроконтроллерах, то такая задержка может потребоваться, например, для подавления “дребезга контактов”.

Как рассчитать время задержки командой NOP

Но что делать, если нужно выполнить задержку не абы как, а на определённое время? Как узнать, на какое время команда NOP задержит выполнение программы?

Приблизительно это можно рассчитать. Для этого потребуется знать два параметра:

  1. Тактовую частоту процессора.
  2. Количество тактов, которое требуется на выполнение команды NOP.

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

Количество тактов, которое занимает выполнение команды NOP, зависит от процессора (микроконтроллера) и берётся из документации на процессор.

Для примера и для упрощения представим, что команда NOP выполняется за 2 такта, а тактовая частота процессора 1 МГц.

Что такое Герц (Гц)? Это количество колебаний в секунду (курсы по электротехнике и электронике ищи здесь).

1 МГц = 1000000 Гц

То есть каждую секунду в процессоре выполняется миллион тактов (в нашем примере). Если в нашем примере команда NOP выполняется за 2 такта, то получается, что за одну секунду процессор может выполнить таких команд:

1000000 / 2 = 500000

Следовательно, одна такая команда будет выполнена за:

1 / 500000 секунды = 0,002 мс = 2 мкс

То есть одна инструкция NOP в нашем примере задержит выполнение программы на 2 микросекунды. Если же нам потребуется задержать программу, например, на 10 мкс, то нам надо будет вызвать команду NOP пять раз подряд:

При желании можно вызвать инструкции NOP в цикле, но тогда ещё придётся учитывать время на выполнение команды цикла.

А теперь о происхождении мнемоники NOP. Всё, как всегда, просто. Это сокращение словосочетания “Nо OPeration“, что, как вы понимаете, переводится с английского как “нет операции” или “никакая операция”. То есть это отсутствие операции, программа ничего не делает.

Команда nop ассемблер

7.1. Сложение и вычитание.

7.1.1. ADD – команда для сложения двух чисел. Она работает как с числами со знаком, так и без знака.

Логика работы команды:

Возможные сочетания операндов для этой команды аналогичны команде MOV .

По сути дела, это – команда сложения с присвоением, аналогичная принятой в языке C / C ++:

Операнды должны иметь одинаковый размер. Результат помещается на место первого операнда.

После выполнения команды изменяются флаги, по которым можно определить характеристики результата:

  1. Флаг CF устанавливается, если при сложении произошёл перенос из старшего разряда. Для беззнаковых чисел это будет означать, что произошло переполнение и результат получился некорректным.
  2. Флаг OF обозначает переполнение для чисел со знаком.
  3. Флаг SF равен знаковому биту результата (естественно, для чисел со знаком, а для беззнаковых он равен старшему биту и особо смысла не имеет).
  4. Флаг ZF устанавливается, если результат равен 0.
  5. Флаг PF — признак чётности, равен 1, если результат содержит нечётное число единиц.

add ax ,5 ; AX = AX + 5

add dx,cx ;DX = DX + CX

add dx,cl ;Ошибка: разный размер операндов.

7.1.2. SUB — команда для вычитания одного числа из другого. Она работает как с числами со знаком, так и без знака.

Логика работы команды:

Возможные сочетания операндов для этой команды аналогичны команде MOV .

По сути дела, это – команда вычитания с присвоением, аналогичная принятой в языке C / C ++:

Операнды должны иметь одинаковый размер. Результат помещается на место первого операнда.

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

sub ax ,13 ; AX = AX — 13

sub ax , bx ; AX = AX + BX

sub b x,cl ;Ошибка: разный размер операндов.

7.1.3. Инкремент и декремент. Очень часто в программах используется операция прибавления или вычитания единицы. Прибавление единицы называется инкрементом, а вычитание — декрементом. Для этих операций существуют специальные команды процессора: INC и DEC. Эти команды не изменяют значение флага CF.

Эти команды содержит один операнд и имеет следующий синтаксис:

Логика работы команд:

В качестве инкремента допустимы регистры и память: reg , mem .

inc ax ; AX = AX + 1

dec ax ; AX = AX — 1

7.1.4. NEG – команда для изменения знака операнда.

Логика работы команды:

В качестве декремента допустимы регистры и память: reg , mem .

7.2. Сложение и вычитание с переносом.

В системе команд процессоров x86 имеются специальные команды сложения и вычитания с учётом флага переноса (CF). Для сложения с учётом переноса предназначена команда ADC, а для вычитания — SBB. В общем, эти команды работают почти так же, как ADD и SUB, единственное отличие в том, что к младшему разряду первого операнда прибавляется или вычитается дополнительно значение флага CF.

Они позволяют выполнять сложение и вычитание многобайтных целых чисел, длина которых больше, чем разрядность регистров процессора (в нашем случае 16 бит). Принцип программирования таких операций очень прост — длинные числа складываются (вычитаются) по частям. Младшие разряды складываются(вычитаются) с помощью обычных команд ADD и SUB, а затем последовательно складываются(вычитаются) более старшие части с помощью команд ADC и SBB. Так как эти команды учитывают перенос из старшего разряда, то мы можем быть уверены, что ни один бит не потеряется. Этот способ похож на сложение(вычитание) десятичных чисел в столбик.

На следующем рисунке показано сложение двух двоичных чисел командой ADD:

При сложении происходит перенос из 7-го разряда в 8-й, как раз на границе между байтами. Если мы будем складывать эти числа по частям командой ADD, то перенесённый бит потеряется и в результате мы получим ошибку. К счастью, перенос из старшего разряда всегда сохраняется в флаге CF. Чтобы прибавить этот перенесённый бит, достаточно применить команду ADC:

//Сложение двух чисел с учетом переноса: FFFFFFAA + FFFF

Команда NOP

Дата добавления: 2015-08-31 ; просмотров: 749 ; Нарушение авторских прав

Команда «нет операции» выполняет холостой ход и не влияет на регистры и флаги, кроме как на счетчик команд (РС).

Ассемблер:NOP
Код:
0 0 0 0 0 0 0 0
Время:1 цикл
Алгоритм:(PC):=(PC)+1
Пример:Пусть требуется создать отрицательный выходной импульс на порте P1[6] длительностью 3 цикла. Это выполнит следующая последовательность команд: CLR P1.6 ;P1[6]:=0 NOP NOP NOP SETB P1.6 ;P1[6]:=1

Команда ORL ,

Команда «логическое «ИЛИ» для переменных байтов» выполняет операцию логического «ИЛИ» над битами указанных переменных, записывая результат в байт назначения. Эта команда на флаги не влияет. Допускается шесть комбинаций режимов адресации:

    • если байтом назначения является аккумулятор :
  1. регистровый
  2. прямой
  3. косвенно-регистровый
  4. непосредственный
    • если байтом назначения является прямой адрес :
  5. к аккумулятору
  6. к константе
Ассемблер:ORL A,Rn ; где n=0-7
Код:
0 1 0 0 1 rrr
, где rrr=000-111
Время:1 цикл
Алгоритм:(A) : = (A) OR (Rn), где OR — операция логического «ИЛИ»
Пример:;(A)=15H, (R5)=6CH ORL A,R5 ;(A)=7DH, (R5)=6CH
Ассемблер:ORL A,
Код:
0 1 0 0 0 1 0 1
direct address
Время:1 цикл
Алгоритм:(A) : =(A) OR (direct)
Пример:;(A)=84H, (PSW)=C2H ORL A,PSW ;(A)=C6H, (PSW)=C2H
Ассемблер:ORL A,@Ri ; где i=0,1
Код:
0 1 0 0 0 1 1 i
Время:1 цикл
Алгоритм:(A) : =(A) OR ((Ri))
Пример:;(A)=52H, (R0)=6DH, (ОЗУ [6D])=49H ORL A,@R0 ;(A)=58H, (ОЗУ [6D])=49H
Ассемблер:ORL A, #data
Код:
0 1 0 0 0 1 0 0
#data8
Время:1 цикл
Алгоритм:(A) : = (A) OR #data
Пример:;(A)=FOH ORL A,#0AH ;(A)=FAH
Ассемблер:ORL , A
Код:
0 1 0 0 0 0 1 0
direct address
Время:1 цикл
Алгоритм:(direct) : = (direct) OR (A)
Пример:;(A)=34H, (IP)=23H ORL IP,A ;(IP)=37H, (A)=34H
Ассемблер:ORL (direct), #
Код:
0 1 0 0 0 0 1 1
direct address
#data8
Время:2 циклa
Алгоритм:(direct) : = (direct) OR #
Пример:;(P1)=00H ORL P1,#0C4H ;(P1)=11000100B (C4H)

Примечание. Если команда используется для работы с портом, величина, используемая в качестве исходных данных порта, считывается из «защелки» порта, а не с выводов БИС.

Команда ORL C,

Команда «логическое «ИЛИ» для переменных битов» устанавливает флаг переноса С, если булева величина равна логической «1», в противном случае устанавлиается флаг С в «0». Косая дробь («/») перед операндом на языке ассемблера указывает на то, что в качестве операнда используется логическое отрицание значения адресуемого бита, но сам бит источника не изменяется. Эта команда на другие флаги не влияет.

Ассемблер:ORL C,
Код:
0 1 1 1 0 0 1 0
bit address
Время:2 циклa
Алгоритм:(C) : =(C) OR (bit)
Пример:;(C)=0, (P1)=53H (01010011B) ORL C,P1.4 ;(C)=1, (P1)=53H (01010011B)
Ассемблер:ORL C,/
Код:
1 0 1 0 0 0 0 0
bit address
Время:2 циклa
Алгоритм:(C) : = (C) OR /(bit)
Пример:;(C)=0, (ОЗУ[25])39H (0011100B) ORL C,/2A ;(C)=1, (ОЗУ[25])39H (0011100B)

Команда POP

Команда «чтение из стека» считывает содержимое ячейки, которая адресуется с помощью указателя стека, в прямо адресуемую ячейку ОЗУ, при этом указатель стека уменьшается на единицу.

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

Ассемблер:POP
Код:
1 1 0 1 0 0 0 0
direct address
Время:2 циклa
Алгоритм:(direct):=((SP)), (SP):=(SP)-1
Пример:;(SP)=32H, (DPH)=01, (DPL)=ABH, ;(ОЗУ[32])=12H, (ОЗУ[32])=56H, POP DPH POP DPL ;(SP)=30H, (DPH)=12H, (DPL)=56H, ;(ОЗУ[32])=12H, (ОЗУ[31])=56H POP SP ;(SP)=20H, (ОЗУ[30])=20H

Команда PUSH

Команда «запись в стек» увеличивает указатель стека на единицу и после этого содержимое указанной прямо адресуемой перемнной копируется в ячейку внутреннего ОЗУ, адресуемого с помощью указателя стека. На флаги эта команда не влияет и используется для записи промежуточных данных в стек.

Команды ассемблера

Арифметические операции — ADD, SUB, MUL, DIV. Многие опкоды делают вычисления. Вы можете узнать многие из них по их названиям: add (addition — добавление), sub (substraction — вычитание), mul (multiply — умножение), div (divide — деление).

Опкод add имеет следующий синтаксис:

Выполняет вычисление: приемник = приемник + источник.

Имеются также другие формы:

приемникисточникпример
регистррегистрadd ecx, edx
регистрпамятьadd ecx, dword ptr [104h] / add ecx, [edx]
регистрзначениеadd eax, 102
памятьзначениеadd dword ptr [401231h], 80
памятьрегистрadd dword ptr [401231h], edx

Эта команда очень проста. Она добавляет значение источника к значение приемника и помещает результат в приемник. Другие математические команды:

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

размер источникаделениечастное в.остаток в.
BYTE (8-bits)ax / делительALAH
WORD (16-bits)dx:ax* / делительAXDX
DWORD (32-bits)edx:eax* / делительEAXEDX

* = Например: если dx = 2030h, а ax = 0040h, dx: ax = 20300040h. Dx:ax — значение dword, где dx представляет старшее word, а ax — младшее. Edx:eax — значение quadword (64 бита), где старшее dword в edx и младшее в eax.

Источник операции деления может быть:

  1. 8-бит регистр (al, ah, cl. )
  2. 16-бит регистр (ax, dx, . )
  3. 32-бит регистр (eax, edx, ecx. )
  4. 8-бит значение из памяти (byte ptr [xxxx])
  5. 16-бит значение из памяти (word ptr [xxxx])
  6. a 32-бит значение памяти (dword ptr [xxxx])

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

Логические операции с битами — OR, XOR, AND, NOT.Эти команды работают с приемником и источником, исключение команда ‘NOT’. Каждый бит в приемнике сравнивается с тем же самым битом в источнике, и в зависимости от команды, 0 или 1 помещается в бит приемника:

командаANDORXORNOT
Бит источника1111111
Бит приемника111111XX
Бит результата11111111

AND (логическое И)устанавливает бит результата в 1, если оба бита, бит источника и бит приемника установлены в 1.

OR (логическое ИЛИ)устанавливает бит результата в 1, если один из битов, бит источника или бит приемника установлен в 1.

XOR (НЕ ИЛИ)устанавливает бит результата в 1, если бит источника отличается от бита приемника.

NOTинвертирует бит источника.

Выполнение операции XOR на этими битами:

Новое значение в ax, после выполнения команды — 0001111010100101 (7845 — в десятичном, 1EA5 — в шестнадцатиричном).

Если вы выполните инверсию каждого бита, то получите:

Значит после операции NOT, ecx будет содержать 0000FFFFh.

Увеличение/Уменьшение — INC/DEC.Есть 2 очень простые команды, DEC и INC. Эти команды увеличивают или уменьшают содержимое памяти или регистра на единицу. Просто поместите:

Ещё одна команда сравнения — test.Команда Test выполняет операцию AND (логическое И) с двумя операндами и в зависимости от результата устанавливает или сбрасывает соответствующие флаги. Результат не сохраняется. Test используется для проверки бит, например в регистре:

Команда jnz выполнит переход, если в регистре eax третий бит справа — установлен. Очень часто комманду test используют для проверки, равен ли регистр нулю:

Команда jz выполнит переход, если ecx = 0.

Ничего не делающая команда — nop. Эта команда не делает абсолютно ничего (пустая команда). Она только занимает пространство и время. Используется для резервирования места в сегменте кода или организации программной задержки.

Обмен значениями — XCHG. Команда XCHG также весьма проста. Назначение: обмен двух значений между регистрами или между регистрами и памятью:

Вот и конец урока. Надеюсь, этот не был скучным. Следующий урок расскажет вам про подпрограммы.

Читать еще:  Язык си ввод
Ссылка на основную публикацию
Adblock
detector