Суббота
18.05.2024
11:18
Форма входа
Категории раздела
Макроинструкции [3]
Управление данными [4]
Макросы [0]
ПК и железо [0]
Осиписание. :) [1]
Разное [4]
Поиск
Друзья сайта
  • Официальный блог
  • Сообщество uCoz
  • FAQ по системе
  • Инструкции для uCoz
  • Статистика

    Онлайн всего: 1
    Гостей: 1
    Пользователей: 0

    OPEN SOURCE PROJECT

    Каталог статей

    Главная » Статьи » Макроинструкции

    Инструкции часть вторая
    Условные инструкции перехода осуществляют или не осуществляют передачу управления в зависимости от состояния флагов CPU во время вызова этих инструкций. Мнемоники условных переходов могут быть получены добавлением условных мнемоников (смотри таблицу 2.1) к символу "j", например инструкция "jc" осуществляет передачу управления, если установлен флаг CF. Условные переходы могут быть только близкие и прямые и могут быть оптимизированы (смотри 1.2.5), операндом должно быть число, определяющее адрес назначения.
       Таблица 2.1  Условия
      ┌──────────┬───────────────────────┬────────────────────────┐
      │ Мнемоник │ Тестируемое условие   │ Описание               │
      ╞══════════╪═══════════════════════╪════════════════════════╡
      │ o        │ OF = 1                │ переполнение           │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ no       │ OF = 0                │ нет переполнения       │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ c        │                       │ перенос                │
      │ b        │ CF = 1                │ меньше                 │
      │ nae      │                       │ не больше и не равно   │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ nc       │                       │ нет переноса           │
      │ ae       │ CF = 0                │ выше или равно         │
      │ nb       │                       │ не ниже                │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ e        │ ZF = 1                │ равно                  │
      │ z        │                       │ ноль                   │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ ne       │ ZF = 0                │ не равно               │
      │ nz       │                       │ не ноль                │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ be       │ CF or ZF = 1          │ ниже или равно         │
      │ na       │                       │ не выше                │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ a        │ CF or ZF = 0          │ выше                   │
      │ nbe      │                       │ не ниже и не равно     │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ s        │ SF = 1                │ знаковое               │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ ns       │ SF = 0                │ беззнаковое            │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ p        │ PF = 1                │ четное                 │
      │ pe       │                       │                        │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ np       │ PF = 0                │ нечетное               │
      │ po       │                       │                        │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ l        │ SF xor OF = 1         │ меньше                 │
      │ nge      │                       │ не больше и не равно   │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ ge       │ SF xor OF = 0         │ больше или равно       │
      │ nl       │                       │ не меньше              │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ le       │ (SF xor OF) or ZF = 1 │ меньше или равно       │
      │ ng       │                       │ не больше              │
      ├──────────┼───────────────────────┼────────────────────────┤
      │ g        │ (SF xor OF) or ZF = 0 │ больше                 │
      │ nle      │                       │ не меньше и не равно   │
      └──────────┴───────────────────────┴────────────────────────┘
        "loop" - это условные переходы, которые используют значение из CX (или ECX) для определения количества повторений цикла. Все инструкции "loop" автоматически уменьшают на единицу CX (или ECX) и завершают цикл, когда CX (или ECX) равно нулю. CX или ECX  используется в зависимости от от текущей утановки битности кода - 16-ти или 32-битной, но вы можете принудительно использовать CX с помощью мнемоника "loopw", или ECX с помощью мнемоника "loopd".
        "loope" и "loopz" это синонимы этой инструкции, которые работают так же, как стандартный "loop", но еще завершают работу, если установлен ZF. "loopew" и "loopzw" заставляют использовать регистр CX, а "looped" и "loopzd" заставляют использовать регистр ECX.
        "loopne" и "loopnz" это тоже синонимы той же инструкции, которые работают так же, как стандартный "loop", но еще завершают работу, если ZF сброшен на ноль. "loopnew" и "loopnzw" заставляют использовать регистр CX, а "loopned" и "loopnzd" заставляют использовать регистр ECX.
        Каждая инструкция "loop" требует операндом число, определяющее адрес назначения, причем это может быть только близкий переход (в пределах 128 байт назад и 127 байт вперед от адреса инструкции, следующей за "loop").
        "jcxz" переходит к метке, указанной в инструкции, если находит в CX ноль, "jecxz" делает то же, но проверяет регистр ECX. Правила для операндов такие же, как с инструкцией "loop".
        "int" активирует стандартный сервис прерывания, который соответствует числу, указанному как операнд в мнемонике. Это число должно находиться в пределах от 1 до 255. Стандартный сервис прерывания заканчивается мнемоником "iret", которая возвращает управление инструкции, следующей за "int". "int3" кодирует короткое (в один байт) системное прерывание, которое вызывает прерывание 3. "into" вызывает прерывание 4, если установлен флаг OF.
        "bound" проверяет, находится ли знаковое число, содержащееся в указанном регистре в нужных пределах. Если число в регистре меньше нижней гранцы или больше верхней, вызывается прерывание 5. Инструкция нуждается в двух операндах, первый - это тестируемый регистр, вторым должен быть адрес в памяти для двух знаковых чисел, указывающих границы. Операнды могут быть размером "word" или "dword".

        bound ax,[bx]    ; тестирует слово на границы
        bound eax,[esi]  ; тестирует двойное слово на границы

    2.1.7  Инструкции ввода-вывода
    "in" переводит байт, слово или двойное слово из порта ввода в AL, AX или EAX. Порты ввода-вывода могут быть адресованы либо напрямую, непосредственно с помощью байтового значения, либо непрямо через регистр DX. Операндом-адресатом должен быть регистр AL, AX или EAX. Операндом-источником должно быть число от 0 до 255 либо регистр DX.

        in al,20h        ; ввод байта из порта 20
        in ax,dx         ; ввод слова из порта, адресованного регистром DX

        "out" переводит байт, слово или двойное слово из порта вывода в AL, AX или EAX. Программа может может определить номер порта, используя те же методы, что и в инструкции "in".  Операндом-адресатом должен быть регистр AL, AX или EAX. Операндом-источником должно быть число от 0 до 255 либо регистр DX.

        out 20h,ax       ; вывод байта в порт 20
        out dx,al        ; вывод слова в порт, адресованный регистром DX

    2.1.8  Строковые операции
    Строковые операции работают с одним элементом строки. Этим элементом может быть байт, слово или двойное слово. Строковые элементы адресуются регистрами SI и DI (или ESI и EDI). После каждой сроковой операции SI и/или DI (или ESI и/или EDI) автоматически обновляются до указателя на следующий элемент строки. Если DF (флаг направления) равен нулю, регистры индекса увеличиваются, если DF равен единице, они уменьшаются. Число, на которое они увеличиваются или уменьшаются равно 1, 2 или 4 в зависимости от размера элемента строки. Каждая инструкция строковой операции имеет короткую форму без операндов, использующую SI и/или DI если тип кода 16-битный, и ESI и/или EDI если тип кода 32-битный. SI и ESI по умолчанию адрес данных в сегменте, адресованном регистром DS, DI и EDI всегда адресует данные в сегменте, выбранном в ES. Короткая форма образуется добавлением к мнемонику строковой операции буквы, определяющей размер элемента строки, для байта это "b", для слова это "w", для двойного слова это "d". Полная форма инструкции требует операнды, указывающие размер оператора, и адресы памяти, которыми могут быть SI или ESI с любым сегментным префиксом, или DI или EDI всегда с сегментным префиксом ES.
        "movs" переводит строковый элемент, на который указывает SI (или ESI) в место, на которое указывает DI (или EDI). Размер операнда может быть байтом, словом или двойным словом. Операндом-адресатом должна быть память, адресованная DI или EDI, операндом-источником должна быть память, адресованная SI или ESI с любым сегментным префиксом.

        movs byte [di],[si]        ; переводит байт
        movs word [es:di],[ss:si]  ; переводит слово
        movsd                      ; переводит двойное слово

        "cmps" вычитает строковый элемент-адресат из строкового элемента-источника и обновляет флаги AF, SF, PF, CF и OF, но не изменяет никакой из сравниваемых элементов. Если стрововые элементы эквивалентны, устанавливается ZF, иначе он очищается. Первым операндом этой инструкции должен быть строковый элемент, адресованный SI или ESI с любым сегментным префиксом, вторым операндом должен быть строковый элемент, адресованный DI или EDI.

        cmpsb                      ; сравнение байтов
        cmps word [ds:si],[es:di]  ; сравнение слов
        cmps dword [fs:esi],[edi]  ; сравнение двойных слов

        "scas" вычитает строковый элемент-адресат из AL, AX или EAX (в зависимости от размера этого элемента) и обновляет флаги AF, SF, ZF, PF, CF и OF. Если значения эквивалентны, устанавливается ZF, иначе он очищается. Операндом должен быть строковый элемент, адресованный DI или EDI.

        scas byte [es:di]          ; сканирует байт
        scasw                      ; сканирует слово
        scas dword [es:edi]        ; сканирует двойное слово

        "stos" помещает значение AL, AX или EAX в строковый элемент-адресат. Правила для операндов такие же, как с инструкцией "scas".
        "lods" строковый элемент в AL, AX или EAX. Операндом должен быть строковый элемент, адресованный SI или ESI с любым префиксом сегмента.

        lods byte [ds:si]          ; загружает байт
        lods word [cs:si]          ; загружает слово
        lodsd                      ; загружает двойное слово

        "ins" переводит байт, слово или двойное слово порта ввода, адресованного регистром DX в строковый элемент-приемник. Операндом-адресатом должна быть память, адресованная DI или EDI, операндом-источником должен быть регистр DX.

        insb                       ; ввод байта
        ins word [es:di],dx        ; ввод слова
        ins dword [edi],dx         ; ввод двойного слова

        "outs" переводит строковый элемент-источник в порт вывода, адресованный регистром DX. Операндом-адресатом должн быть регистр DX, а операндом-источником должна быть память, адресованная SI или ESI с любым префиксом сегмента.

        outs dx,byte [si]          ; вывод байта
        outsw                      ; вывод слова
        outs dx,dword [gs:esi]     ; вывод двойного слова

        Префиксы повторения "rep", "repe"/"repz" и "repne"/"repnz" определяют повторяющуюся строковую операцию. Если инструкция строковой операции имеет префикс повторения, операция выполняется повторно, каждый раз используя другой элемент строки. Повторение прекратится, когда будет выполнено одно из условий, указанных префиксом. Все три префикса автоматически уменьшают регистр CX или ECX (в зависимости от того, какую адресацию использует инструкция строковой операции, 16-битную или 32-битную) после каждой операции и повторяют ассоциированную операцию, пока CX или ECX не станет равным нулю. "repe"/"repz" и "repne"/"repnz" используются только с инструкциями "scas" и "cmps" (описанными выше). Когда используются эти префиксы, повторение следующей инструкции зависит также от флага нуля (ZF), "repe" и "repz" прекращают выполнение, если ZF равен нулю, "repne" и "repnz" прекращают выполнение, если ZF равен единице.

        rep  movsd       ; переводит несколько двойных слов
        repe cmpsb       ; сравнивает байты, пока эквивалентны

    2.1.9  Инструкции управления флагами

    Инструкции управления флагами обеспечивают метод прямого изменения состояния битов во флаговом регистре. Все инструкции, описанные в этом разделе, не имеют операндов.
        "stc" устанавливает CF (флаг переноса) в 1, "clc" обнуляет CF, "cmc" изменяет  CF на его дополнение.
        "std" устанавливает DF (флаг направления) в 1, "cld" обнуляет DF.
        "sti" устанавливает IF (флаг разрешения прерываний) в 1 и таким образом разрешает прерывания, "cli" обнуляет IF и таким образом запрещает прерывания.
        "lahf" копирует SF, ZF, AF, PF и CF в биты 7, 6, 4, 2 и 0 регистра AH. Содержание остальных битов неопределено. Флаги остаются неизменными.
        "sahf" переводит биты 7, 6, 4, 2 и 0 из регистра AH в SF, ZF, AF, PF и CF.
        "pushf" уменьшает ESP на два или на четыре и сохраняет нижнее слово или двойного слово флагового регистра в вершине стека. Размер сохраненной информации зависит от текущей настройки кода. Вариант "pushfw" сохранят слово, независимо от настройки кода, "pushfd" также независимо от настройки кода сохраняет двойное слово.
        "popf" переводит определенные биты из слова или двойного слова в вершине стека и увеличивает ESP на два или на четывре, в зависимости от текущей настройки кода. Вариант "popfw" сохранят слово, независимо от настройки кода, "popfd" также независимо от настройки кода сохраняет двойное слово.

    2.1.10  Условные операции
    Инструкции, образванные с помощью добавления условного мнемоника (смотрите таблицу 2.1) к мнемонику "set" присваивают байту единицу, если условие истинно, и ноль, если если условие не выполняется. Операндом должен быть 8-битный регистр общего назначения либо байт в памяти.

        setne al         ; единицу в al, если флаг нуля пустой
        seto byte [bx]   ; единицу в байт, если есть переполнение

        "calc" присваивает всем битам регистра AL единицу, если стоит флаг переноса, и нули в другом случае. У этой инстркции нет аргументов.
        Иннструкции, образованные добавлением условного мнемоника к "cmov" переводят слово или двойное слово из регистра общего назначения или памяти в регистр общего назначения только если условие верно. Операндом-адресатом должен быть регистр общего назначения, операндом-источником - регистр общего назначения либо память.

        cmove ax,bx      ; переводит, если установлен флаг нуля
        cmovnc eax,[ebx] ; переводит, если очищен флаг переноса

        "cmpxchg" сравнивает значение в регистре AL, AX или EAX с операндом-адресатом. Если значения равны, операнд-источник загружается в операнд-адресат, иначе операнд-адресат загружается в регистр AL, AX или EAX. Операндом-адресатом должен быть регистр общего назначения или память, операндом-источником - регистр общего назначения.

        cmpxchg dl,bl    ; сравнивает и меняет с регистром
        cmpxchg [bx],dx  ; сравнивает и меняет с памятью

        "cmpxchg8b" сравнивает с операндом 64-битное значение в регистрах EDX и EAX. Если значения раны, 64-битное значение в регистрах EDX и EAX сохраняется в операнде, иначе значение из операнда загружается в эти регистры. Операндом должно быть четверное слово в памяти.

        cmpxchg8b [bx]   ; сравнивает и меняет 8 битов

    2.1.11  Разные инструкции
    "nop" занимает один бит, но ничего не значит, кроме как указатель инструкции. У неё нет операндов и она ничего не совершает.
        "ud2" генерирует недопустимый опкод. Эта инструкция создана для тестирования прграммного обеспечения, чтобы недвусмысленно генерировать недопустимый опкод. У инструкции нет операндов.
        "xlat" заменяет байт в регистре AL байтом, индексированным его значением в таблице перевода, адресованной BX или EBX. Операндом должен быть байт памяти, адресованный регистром BX или EBX с любым сегментным префиксом. Эта инструкция также имеет короткую форму "xlatb", которая не использует операнды и использует адрес из BX или EBX (в зависимости от настройки кода) в сегменте, адресованном DS.
        "lds" переводит переменный указатель из операнда-источника в DS и регистр-адресат. Операндом-источником должна быть память, а операндом-адресатом - регистр общего назначения. Регистр DS получает селектор сегмента указателя, а регистр-адресат получает его смещение. "les", "lfs" "lgs" и "lss" работают точно так же, как "lds", только вместо регистра DS используются соответственно ES, FS, GS или SS.

        lds bx,[si]      ; загружает указатель в ds:bx

        "lea" переводит смещение операнда-источника (вместо его значения) в операнд-адресат. Операндом-источником должна быть память, а операндом-адресатом должен быть регистр общего назначения.

        lea dx,[bx+si+1] ; загружает исполнительный адрес в dx

        "cpuid" возвращает идентификацию процессора и информацию о его свойствах в регистры EAX, EBX, ECX и EDX. Выдаваемая информация выбирается вводом нужного значения в регистр EAX перед тем, как выполнить иструкцию. У этой инструкции нет операндов.
        "pause" задерживает выполнение следующей инструкции, реализуясь оперделенное количество времени. Эта инструкция может быть использована, чтобы улучшить выполнение циклов ожидания. У инструкции нет операндов.
        "enter" создает стековый фрейм, который может быть использован для реализации свода правил блочных языков высокого уровня. Инструкция "leave" в конце процедуры дополняет "enter" в начале процедуры, чтобы упростить управление стеком и контролировать доступ к переменным для вложенных процедур. Инструкция "enter" имеет два параметра. Первый параметр определяет количество байт динамической памяти, которое должно быть отведено для введенной подпрограммы. Второй параметр соответствует лексическому уровню вложенности подпрограммы, может находится в области от 0 до 31. Указанный лексический уровень устанавливает, сколько наборов указателей стековых фреймов CPU копирует в новый стековый фрейм из предыдущего фрейма. Этот список указателей стековых фреймов иногда называется дисплеем. Первое слово (или двойное слово, если код 32-битный) дисплея - это указатель на последний стековый фрейм. Этот указатель делает возможным для инструкции "leave" совершить в обратном порядке действия предыдущей инструкции "enter", эффективно сбрасывая последний стековый фрейм. После того, как "enter" создает новый дисплей для процедуры, инструкция выделяет для неё место в динамической памяти, уменьшая ESP на количество байтов, определенных в первом параметре. Чтобы процедура могла адресовать свой дисплей, "enter" передает указатель BP (или EBP) в начало нового стекового фрейма. Если лексический уровень равен нулю, "enter" сохраняет BP (или EBP), копирует SP в BP (или ESP в EBP) и далее вычитает первый операнд из SP (или ESP). Для уровней вложенности больших нуля процессор сохраняет дополнительные указатели фреймов в стек перед подгонкой указателя стека.

        enter 2048,0     ; ввод и выделение 2048 байтов в стеке


    2.1.12  Системные инструкции

    "lmsw" загружает операнд в слово машинного статуса (биты от 0 до 15 регистра CR0), тогда как "smsw" сохраняет слово машинного статуса в операнд-адресат. Операндом может быть 16-битный или 32-битный регистр общего назначения или слово в памяти.

        lmsw ax          ; загружает машинный статус из регистра
        smsw [bx]        ; сохраняет машинный статус в память

        "lgdt" и "lidt" загружают значения из операнда в регистр таблицы глобальных дескрипторов или в регистр таблицы дескриптров прерываний соответственно. "sgdt" и "sidt" сохраняют содержимое регистра таблицы глобальных дескрипторов или регситра таблицы дескриптров прерываний в операнд-адресат. Операндом должны быть 6 байтов в памяти.

        lgdt [ebx]       ; загружает таблицу глобальных дескрипторов

        "lldt" загружает операнд в поле селектора сегмента регистра таблицы локальных дескрипторов, а "sldt" сохраняет селектор сегмента из регистра таблицы локальных дескрипторов в операнд. "ltr" загружает операнд в поле селектора сегмента регистра задачи, а "str" сохраняет селектор сегмента из регистра задачи в операнд. Правила для операндов такие же, как в инструкциях "lmsw" и "smsw".
        "lar" загружает права доступа из сегментного дескриптора, указанного селектором в операнде-источнике, в операнд-адресат и ставит флаг ZF. Операндом-адресатом может быть 16-битный или 32-битный регистр общего назначения. Операндом-источником должен быть 16-битный регистр общего назначения или память.

        lar ax,[bx]      ; загружает права доступа в слово
        lar eax,dx       ; загружает права доступа в двойное слово

        "lsl" загружает сегментный предел из сегментного дескриптора, указанного селектором в операнде-источнике, в операнд-адресат и ставит флаг ZF. Правила для операндов такие же, как в инструкции "lsl".
        "verr" и "verw" проверяют, поддаётся ли чтению или записи на данном уровне привилегий сегмент кода или данных, заданный в операнде. Операндом должно быть слово, это может быть регистр общего назначения или память. Если сегмент доступен и читаем (для "verr") или изменяем, устанавливается флаг ZF, иначе он очищается. Правила для операндов такие же, как в инструкции "lldt".
        "arpl" сравнивает поля RPL (уровень привилегий запрашивающего) двух селекторов сегментов. Первый операнд содержит один селектор сегмента, второй содержит другой. Если поле RPL операнда-адресата меньше, чем поле RPL операнда-источника, то устанавливается флаг ZF, и поле RPL операнда-адресата увеличивается до соответствия операнду-источнику. Иначе флаг ZF очищается и в операнде никаких изменений не производится. Операндом-адресатом должен быть регистр общего назначения или память длиной в слово, операндом-источником должен быть регистр общего назначения тоже длиной в слово.

        arpl bx,ax       ; подгоняет RPL селектора в регистре
        arpl [bx],ax     ; подгоняет RPL селектора в памяти

        "clts" очищает флаг TS (переключение задач) в регистре CR0. У этой инструкции нет операндов.
        Префикс "lock" заставляет процессор объявить сигнал "bus-lock" (или LOCK#) во время выполнения сопутсвующей инструкции. В многопроцессорной среде сигнал "bus-lock" гарантирует, что пока он объявлен, процессор эксклюзивно использует любую общую память. Префикс "lock" может быть присоединен только к следующим инструкциям и причем только к тем их формам, в которых операндом-адресатом является память: "add", "adc", "and", "btc", "btr", "bts", "cmpxchg", "cmpxchg8b", "dec", "inc", "neg", "not", "or", "sbb", "sub", "xor", "xadd" и "xchg". Если этот префикс используется с одной из этих инструкций, но операндом-источником является память, может быть сгенерирован не определенный ошибочный опкод. Он может быть сгенерирован также, если префикс "lock" используется с инструкцией, не перечисленной выше. Инструкция "xchg" всегда объявляет сигнал "bus-lock", независимо от отсутствия или присутствия преикса "lock".
        "hlt" прекращает выполнение инструкции и переводит прощессор в состояние остановки. Запущенное прерывание, отладочное исключение, BINIT, INIT или RESET продолжат выполнение. У этой инструкции нет операндов.
        "rdmsr" загружает содержимое 64-битного MSR (модельно-специфический регистр) по адресу, определенному в ECX, в EDX и EAX. "wrmsr" загружает содержимое регистров EDX и EAX в 64-битный MSR по адресу, определенному в ECX. "rdtsc" загружает текущее значение счетчика времени процессора из 64-битного MSR в регистры EDX и EAX. Процессор увеличивает значение счетчика времени MSR каждый цикл тактового генератора и сбрасывается на 0, когда процессор перезагружается. "rdpmc" загружает содержимое 40-битного счетчика событий производительности, заданного в ECX, в EDX и EAX. Эти инструкции не имеют операндов.
        "wbinvd" совершает обратную запись модифицированных строк внутреннего кэша процессора в основную память и аннулирует (очищает) внутренние кэши. Далее инструкция запускает специальный цикл шины, который предназначает внешним кэшам также совершить обратную запись модифицированных данных и другой цикл шины, который указывает, что внешние кэши должны аннулироваться. Эта инструкция не имеет операндов.

    Категория: Макроинструкции | Добавил: fasm (19.07.2008)
    Просмотров: 1299 | Рейтинг: 0.0/0
    Всего комментариев: 0
    Добавлять комментарии могут только зарегистрированные пользователи.
    [ Регистрация | Вход ]