Tooprogram.ru

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

Команды пересылки данных ассемблер

Команды пересылки данных

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

•пересылки данных общего назначения

•ввода-вывода в порт

•работы с адресами и указателями

•работы со стеком

Команды пересылки данных общего назначения

К этой группе относятся следующие команды:

mov — это основная команда пересылки данных . Она реализует самые разнообразные варианты пересылки.

Отметим особенности применения этой команды:

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

К примеру, рассмотрим фрагмент программы для пересылки байта из ячейки fls в ячейку fld:

. нельзя загрузить в сегментный регистр значение непосредственно из памяти. Поэтому для выполнения такой загрузки нужно использовать промежуточный объект. Это может быть регистр общего назначения или стек. В начале сегмента кода две команды mov, выполняющие настройку сегментного регистра ds. При этом из-за невозможности загрузить впрямую в сегментный регистр значение адреса сегмента, содержащееся в предопределенной переменной @data, приходится использовать регистр общего назначения ax;

. нельзя переслать содержимое одного сегментного регистра в другой сегментный регистр. Это объясняется тем, что в системе команд нет соответствующего кода операции. Но необходимость в таком действии часто возникает. Выполнить такую пересылку можно, используя в качестве промежуточных все те же регистры общего назначения. Вот пример инициализации регистра es значением из регистра ds:

Но есть и другой, более красивый способ выполнения данной операции — использование стека и команд push и pop:

push ds ;поместить значение регистра ds в стек

pop es ;записать в es число из стека

. нельзя использовать сегментный регистр cs в качестве операнда назначения. Причина здесь простая. Дело в том, что в архитектуре микропроцессора пара cs:ip всегда содержит адрес команды, которая должна выполняться следующей. Изменение командой mov содержимого регистра cs фактически означало бы операцию перехода, а не пересылки, что недопустимо.

Схема команды: mov приемник,источник

Назначение: пересылка данных между регистрами или регистрами и памятью.

Алгоритм работы: копирование второго операнда в первый операнд.

Состояние флагов после выполнения команды: !! выполнение команды не влияет на флаги

Команда mov применяется для различного рода пересылок данных, при этом, несмотря на всю простоту этого действия, необходимо помнить о некоторых ограничениях и особенностях выполнения данной операции:

•направление пересылки в команде mov всегда справа налево, то есть из второго операнда в первый;

•значение второго операнда не изменяется;

•оба операнда не могут быть из памяти (при необходимости можно использовать цепочечную команду movs );

•лишь один из операндов может быть сегментным регистром;

•желательно использовать в качестве одного из операндов регистр al / ax / eax , так как в этом случае TASM генерирует более быструю форму команды mov .

MOV (MOVe operand to/from system registers)

Пересылка операнда в системные регистры (или из них)

Схема команды: mov приемник,источник

Назначение: пересылка данных между регистрами или регистрами и памятью.

Алгоритм работы: копирование второго операнда в первый.

Состояние флагов после выполнения команды:

11 07 06 04 02 00

OF SF ZF AF PF CF

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

;переключение микропроцессора в защищенный

XCHG (eXCHanGe) Обмен

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

Схема команды: xchg операнд_1,операнд_2

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

Алгоритм работы: обмен содержимого операнд_1 и операнд_2.

Состояние флагов после выполнения команды: выполнение команды не влияет на флаги

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

!! операнды должны иметь один тип.

!! Не допускается (как и для всех команд ассемблера) обменивать между собой содержимое двух ячеек памяти.

xchg ax,bx ;обменять содержимое регистров ax и bx

xchg ax,word ptr [si] ;обменять содержимое регистра ax

Команды пересылки данных

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

Различают четыре типа пересылок: общего назначения, с уча­стием аккумулятора, адреса операнда и флагов. Ни одна из команд этой группы не влияет на флаги, за исключением двух команд, которые осуществляют явную загрузку регистра фла­гов F.

Пересылки общего назначения.Задаются спомощью четырех мнемокодов: MOV (переслать), PUSH (занести в стек), POP (извлечь из стека) и XCHG (обменять).

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

Команда PUSH служит для занесения содержимого 16-раз­рядного источника в стек. Источником операнда может являться регистр, сегментный регистр или память. Выполнению команды предшествует формирование адреса вершины стека: (SP) = (SP) – 2.

Читать еще:  Язык си в примерах

Команда POP служит для извлечения 16-разрядного операнда из стека и пересылки его в регистр, память или сегментный регистр. Операция извлечения из стека завершается формированием нового адреса вершины стека (SP) = (SP) + 2.

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

Пересылки с участием аккумулятора.Состоят из трех команд: IN (ввод), OUT (вывод) и XLAT (трансляция). В отли­чие от рассмотренных выше пересылок общего типа эти коман­ды обязательно используют аккумулятор в качестве источника или места назначения операнда.

Команда IN служит для пересылки данных (байта или слова) из порта ввода в аккумулятор (в AL или АХ). Номер порта ввода может быть задан как непосредственно, во втором байте команды, так и косвенно, в регистре DX, причем только регистр DX из всех РОН может использоваться для этой цели. Если первый формат команды ввода позволяет адресоваться к 256 портам, то второй — к 2 16 = 65536 портам. Косвенное за­дание порта хотя и требует предварительной загрузки его номе­ра в DX, однако позволяет организовывать программные цик­лы, в которых используется изменяющийся номер портов ввода.

Команда OUT служит для пересылки данных (байта или слова) из аккумулятора (из AL или АХ) в порт вывода. Эта команда, как и команда IN, имеет два формата, которые опре­деляют способ адресации порта вывода. Преимущества и недо­статки использования каждого из форматов определяются теми же соображениями, что и для команды IN.

Команда XLAT осуществляет табличное преобразование кодов. Таблица размером не более 256 байт размещается в па­мяти, а ее начальный адрес — в регистре ВХ. При выполнении этой команды содержимое AL использу­ется в качестве относительного адреса строки таблицы, из которой байт пере­сылается в AL.

Пересылки адреса операнда.Включают три команды: LEA (загрузить исполнительный адрес), LDS (загрузить указатель в DS) и LES (загрузить указатель в ES). Эти команды служат средством управления механизмом адресации операндов.

По команде LEA извлекается не сам операнд, а его испол­нительный адрес ЕА. Действие команды состоит в передаче вычисленного 16-разрядного адреса операнда в 16-разрядный регистр, код которого указан в поле reg. Использование коман­ды LEA удобно при составлении подпрограмм, работающих спараметрами. В этом случае перед вызовом подпрограммы выделенный регистр загружается адресом переменной, которая предварительно записана в память в качестве параметра. На­пример, подпрограмма оперирует с параметром, адрес которого содержится в РОН ВХ. Если перед вызовом этой под­программы выполнить команду LEA BX, ALPHA, где ALPHA — имя ячейки памяти, содержащей переменную, то подпрограмма будет использовать в качестве параметра переменную из ячейки ALPHA. Если же перед вызовом подпрограммы выполнить команду LEA BX, BETA, то в качестве значения параметра под­программа будет использовать значение переменной из ячейки с именем BETA.

Команды LDS и LES используются, в основном, при обра­щении к данным, находящимся вне текущих сегментов DS или ES, так, что возникает необходимость изменить базовый адрес сегмента. Пара 16-разрядных адресов — база сегмента и смеще­ние в сегменте, называемая указателем, предварительно загру­жается в память. Относительный адрес указателя определяется значениями полей mod и r/т постбайта команды LDS (или LES). Значение смещения содержится в двух первых байтах указателя, а базовый адрес сегмента — в третьем и четвертом байтах. По команде LDS (или LES) происходит обращение к указателю и осуществляется загрузка регистра DS (или ES) базовым адресом, а смещение пересылается в регистр, указан­ный полем reg постбайта команды.

Пересылки флагов.Включают четыре однобайтовые коман­ды: LAHF (загрузить АН флагами), SAHF (запомнить АН врегистре F), PUSH F (занести F в стек) и POP F (извлечь из стека в F).

По команде LAHF осуществляется пересылка младшего байта регистра флагов F вАН, а по команде SAHF — обратная пересылка. Эти команды введены в систему команд ЦП для упрощения программной совместимости с ВМ80. В частности, без их использования для реализации команд PUSH PSW и POP PSW BM80 с помощью команд ЦП потребовалось бы по 9 байт памяти, а использование, например, команды LAHF позволяет при реализации команды PUSH PSW обой­тись всего двумя байтами: LAHF, PUSH AX. Команда PUSHF помещает содержимое регистра F в стек, причем сначала запи­сывается старший байт, а затем младший байт регистра F.

Команды пересылки данных ассемблер

6.1. Типы операндов.

При изучении данной темы мы рассмотрим всего три типа операндов, которые могут встречаться в любой команде: непосредственно заданное значение (immediate), регистр (register) и память (memory). Из всех перечисленных здесь типов только последний (память) довольно труден для освоения. Список условных обозначений возможных типов операндов, взятых из руководства фирмы Intel по процессору Pentium, приведен в табл. 1. Довайте изучим его, поскольку с этого момента мы будем активно пользоваться этими обозначениями при описании синтаксиса команд процессоров Intel.

Таблица 1. Условное обозначение типов операндов.

Один из 8-разрядных регистров общего назначения: АН, AL, BH, BL, CH, CL, DH, DL

Один из 16-разрядных регистров общего назначения: АХ, BX, СХ, DX, SI, DI, SP, BP

Один из 32-разрядных регистров общего назначения: ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, ESP, EBP

Произвольный регистр общего назначения

Читать еще:  Открыть файл предупреждение системы безопасности

Один из 16-разрядных сегментных регистров: CS, DS, SS, ES, FS, GS

Непосредственно заданное 8-разрядное значение (байт)

Непосредственно заданное 16-разрядное значение (слово)

Непосредственно заданное 32-разрядное значение (двойное слово)

Непосредственно заданное 8-, 16- или 32-разрядное значение

8-разрядный операнд, в котором закодирован один из 8-разрядных регистров общего назначения или адрес байта в памяти

16-разрядный операнд, в котором закодирован один из 16-разрядных регистров общего назначения или адрес слова в памяти

32-разрядный операнд, в котором закодирован один из 32-разрядных регистров общего назначения или адрес двойного слова в памяти

Адрес 8-, 16- или 32-разрядного операнда в памяти

Команда MOV копирует данные из операнда-источника в операнд-получатель. Она относится к группе команд пересылки данных (data transfer) и используется в любой программе. Команда MOV является двуместной (т.е. имеет два операнда): первый операнд определяет получателя данных (destination), а второй — источник данных (source):

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

Практически во всех командах ассемблера операнд-получатель находится слева, а операнд-источник— справа.

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

1. Оба операнда должны иметь одинаковую длину.

2. В качестве одного из операндов обязательно должен использоваться регистр (т.е. пересылки типа «память-память» в команде MOV не поддерживаются).

3. В качестве получателя нельзя указывать регистры CS , EIP и IP .

4. Нельзя переслать непосредственно заданное значение в сегментный регистр.

Ниже приведены варианты использования команды MOV с разными операндами (кроме сегментных регистров):

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

Пересылка типа «память—память». С помощью одной команды MOV нельзя напрямую переслать операнд из одной области памяти в другую. Поэтому вначале нужно загрузить исходное значение в один из регистров общего назначения, а затем переслать его в нужное место памяти.

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

6.3. Команда MOVZX.

Команда MOVZX (Move With Zero-Extend, или Переместить и дополнить нулями) копирует содержимое исходного операнда в больший по размеру регистр получателя данных. При этом оставшиеся неопределенными биты регистра-получателя (как правило, старшие 16 или 24 бита) сбрасываются в ноль. Эта команда используется только при работе с беззнаковыми целыми числами. Существует три варианта команды MOVZX:

MOVZX r 16, r / m 8

MOVZX r 32, r / m 8

Условные обозначения операндов этой команды приведены в табл. 1. В каждом из приведенных трех вариантов первый операнд является получателем, а второй — источником данных. В качестве операнда-получателя может быть задан только 16- или 32-разрядный регистр. На рис. 8 показано, как 8-разрядный исходный операнд загружается с помощью команды MOVZX в 16-разрядный регистр.

Рис. 8. Иллюстрация работы команды MOVZX.

В приведенном ниже примере используются все три варианта команды MOVZX с разными размерами операндов.

movzx eax, bx ; EAX = 0000A69Bh

movzx edx, bl ; EDX = 0000009Bh

movzx cx, bl ; CX = 009Bh

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

char byte1 = 0x9B;

short word1 = 0xA69B;

Команда MOVSX ( Move With Sign — Extend , или переместить и дополнить знаком) копирует содержимое исходного операнда в больший по размеру регистр получателя данных, также как и команда MOVZX . При этом оставшиеся неопределенными биты регистра-получателя (как правило, старшие 16 или 24 бита) заполняются значением знакового бита исходного операнда. Эта команда используется только при работе со знаковыми целыми числами. Существует три варианта команды MOVSX :

MOVSX r 16, r / m 8

MOVSX r 32, r / m 8

MOVSX r 32, r / m 16

При загрузке меньшего по размеру операнда в больший по размеру регистр с помощью команды MOVSX , знаковый разряд исходного операнда дублируется (т.е. переносится или расширяется) во все старшие биты регистра-получателя. Например, при загрузке 8-разрядного значения 10001111 b в 16-разрядный регистр, оно будет помещено в младшие 8 битов этого регистра. Затем, как показано на рис. 9, старший бит исходного операнда переносится во все старшие разряды регистра-получателя.

Рис. 9. Иллюстрация работы команды MOVSX.

В приведенном ниже примере используются все три варианта команды MOVSX с разными размерами операндов.

movsx eax, bx ; EAX = FFFFA69Bh

movsx edx, bl ; EDX = FFFFFF9Bh

movsx cx, bl ; CX = FF9Bh

Команда LAHF ( Load Status Flags Into АН, или загрузить флаги состояния в регистр АН) позволяет загрузить в регистр АН младший байт регистра флагов EFLAGS . При этом в регистр АН копируются следующие флаги состояния: SF (флаг знака), ZF (флаг нуля), AF (флаг служебного переноса), PF (флаг четности) и CF (флаг переноса). С помощью этой команды можно легко сохранить содержимое регистра флагов в переменной для дальнейшего анализа:

wiki.vspu.ru

портал образовательных ресурсов

Содержание

Введение в Ассемблер. Работа с регистрами. Адресация и команды пересылки данных. Арифметические операции с целыми числами

Цели:

Основная нагрузка при работе компьютера ложится на процессор и память. Процессор выполняет команды, хранящиеся в памяти. В памяти хранятся также и данные. Между процессором и памятью происходит непрерывный обмен информацией. Процессор имеет свою небольшую память, состоящую из регистров. Команда процессора, использующая находящиеся в регистрах данные, выполняется много быстрее аналогичных команд над данными в памяти. Поэтому часто для того, чтобы выполнить какую-либо команду, данные для неё предварительно помещают в регистры. Результат команды можно при необходимости поместить обратно в память. Обмен данными между памятью и регистрами осуществляют команды пересылки. Кроме этого, можно обмениваться данными между регистрами, посылать и получать данные от внешних устройств. В регистр и ячейку памяти можно посылать и непосредственный операнд – число. Кроме этого имеются команды, с помощью которых можно помещать и извлекать данные из стека – специальной области памяти, используемой для хранения адресов возврата из функций, передаваемых в функцию параметров и локальных переменных.

Читать еще:  Сегменты в ассемблере

Адресация и выделение памяти

Для процессора вся память представляет собой последовательность однобайтовых ячеек, каждая из которых имеет свой адрес. Для того, чтобы оперировать большими числами, пары ячеек объединяют в слова, пары слов – в двойные слова, пары двойных слов – в учетверенные слова. Чаще всего в программах оперируют байтами, словами и двойными словами (в соответствии с одно-, двух- и четырехбайтовыми регистрами процессоров). Адресом слова и двойного слова является адрес их младшего байта.

Здесь используется доступ к переменной типа BYTE по указателю – структура BYTE PTR [EAX]. Немного позже мы увидим, как этот прием используется при написании программ.

Задания.

Объясните полученный результат (напоминаем, что адресом слова или двойного слова является адрес их младшего байта). Проделайте то же самое, используя указатель типа WORD.

Доступ к переменной по указателю используется и в языках высокого уровня (очень часто – при создании динамических массивов).

Указатель – это переменная, которая содержит адрес другой переменной (говорят, что указатель указывает на переменную того типа, адрес которой он содержит). Существует одноместная (унарная, т.е. для одного операнда) операция взятия адреса переменной & (амперсанд, как в названии мультфильма Tom&Jerry). Если имеем объявление int a, то можно определить адрес этой переменной: &a. Если Pa – указатель, который будет указывать на переменную типа int, то можно записать: Pa=&a. Существует унарная операция * (она называется операцией разыменования), которая действует на переменную, содержащую адрес объекта, т.е. на указатель. При этом извлекается содержимое переменной, адрес которой находится в указателе. Если Pa=&a, то, воздействуя на обе части операцией * получим (по определению этой операции): *Pa=a. Исходя из этого, указатель объявляется так:

Это и есть правило объявления указателя: указатель на переменную какого-то типа – это такая переменная, при воздействии на которую операцией разыменования получаем значение переменной того же типа. На листинге 3 приведен пример использования указателя в языке Си.

На листинге 4 представлена программа, позволяющая получать адреса элементов массивов разных типов средствами Cи. Обратите внимание на значения соседних адресов элементов массива.

Один из наиболее часто встречающихся случаев – использование указателей для динамического выделения памяти при создании массивов (листинг 5).

Задание. Выведите на экран адреса элементов массива, созданного в программе, показанной на листинге 5. Попробуйте создать динамический массив типа double, заполнить его, вывести на печать элементы массива и их адреса.

Арифметические операции над целыми числами

Сложение и вычитание целых чисел

Рассмотрим 3 основные команды сложения. Команда INC осуществляет инкремент, т.е. увеличение содержимого операнда на 1, например, INC EAX. Команда INC устанавливает флаги OF, SF, ZF, AF, PF в зависимости от результатов сложения. Команда ADD осуществляет сложение двух операндов. Результат пишется в первый операнд (приемник). Первый операнд может быть регистром или переменной. Второй операнд – регистром, переменной или числом. Невозможно, однако, осуществлять операцию сложения одновременно над двумя переменными. Команда действует на флаги CF, OF, SF, ZF, AF, PF. Её можно использовать для знаковых и для беззнаковых чисел. Команда ADC осуществляет сложение двух операндов подобно команде ADD и флага (бита) переноса. С её помощью можно осуществлять сложение чисел, размер которых превышает 32 бита или изначально длина операндов превышает 32 бита.

Умножение целых чисел

В отличие от сложения и вычитания умножение чувствительно к знаку числа, поэтому существует две команды умножения: MUL – для умножения беззнаковых чисел, IMUL – для умножения чисел со знаком. Единственным оператором команды MUL может быть регистр или переменная. Здесь важен размер этого операнда (источника).

Команда IMUL имеет 3 различных формата. Первый формат аналогичен команде MUL. Остановимся на двух других форматах.

operand1 должен быть регистр, operand2 может быть числом, регистром или переменной. В результате выполнения умножения (operand1 умножается на operand2, и результат помещается в operand1) может получиться число, не помещающееся в приемнике. В этом случае флаги CF и AF будут равны 1 (0 в противном случае).

В данном случае operand2 (регистр или переменная) умножается на operand3 (число) и результат заносится в operand1 (регистр). Если при умножении возникнет переполнение, т.е. результат не поместится в приемник, то будут установлены флаги CF и OF. Применение команд умножения приведено на листинге 8.

Листинг 8. Применение команд умножения

Деление целых чисел

Деление беззнаковых чисел осуществляется с помощью команды DIV. Команда имеет только один операнд – это делитель. Делитель может быть регистром или ячейкой памяти. В зависимости от размера делителя выбирается и делимое.

Команда знакового деления IDIV полностью аналогична команде DIV. Существенно, что для команд деления значения флагов арифметических операций не определены. В результате деления может возникнуть либо переполнение, либо деление на 0. Обработку исключения должна обеспечить операционная система.

Ссылка на основную публикацию
Adblock
detector