Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1




НазваниеКонспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1
страница4/41
Дата публикации03.03.2013
Размер5.22 Mb.
ТипКонспект
uchebilka.ru > Информатика > Конспект
1   2   3   4   5   6   7   8   9   ...   41
Часть строки исходного текста после символа точки с запятой (если он не явля­ется элементом знаковой константы или строки знаков) считается комментарием и ассемблером игнорируется. Комментарии вносятся в программу как поясняю­щий текст и могут содержать любые знаки до ближайшей комбинации символов возврата каретки и перевода строки (CR/LF).

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

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

Директива присваивания имеет такой формат:
имя-выражение

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

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

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

Примеры определения символических имен:
int - 167

stringl - 'ab'

const - 7*4

addrl – stringl
Директива EQU имеет следующий формат:
имя EQU выражение
Директива EQU создает абсолютное имя, псевдоним или текстовое имя путем присваивания имени указанного выражения. Под абсолютным именем здесь под­разумевается имя, представляющее собой 16-разрядное значение, а псевдонимом называется ссылка на другое имя. В качестве текстового имени может использо­ваться строка символов. При компиляции исходного текста каждое появление имени ассемблер замещает текстом или значением выражения, в зависимости от типа выражения. Имя должно быть уникальным и не может быть переопределе­но. В качестве выражения может задаваться целое число, строковая константа, вещественное число, кодированное вещественное число, мнемоника инструкции, константное или адресное выражение. Выражение, имеющее значением целое число, порождает имя, вхождения которого ассемблер замещает этим значением. Для всех остальных выражений вхождения имени замещаются текстом.

Примеры применения директивы EQU:
k EQU 1024

adr EQU [BP]

cle EQU XOR AX.AX

d EQU BYTE PTR

t EQU 'File'

MASM EQU 5.1 + 0.9

Msft EQU

mat EQU 20*30
Директива LABEL имеет следующий формат:
имя LABEL тип
Директива LABEL порождает новую переменную или метку путем присваи­вания имени указанного типа и текущего значения указателя позиции. Имя должно быть уникальным и не может быть переопределено. В качестве типа может быть задано одно из следующих ключевых слов: BYTE, WORD, DWORD, QWORD, TBYTE, NEAR, FAR.

Примеры использования директивы LABEL:
byte_array LABEL BYTE

word_array DW 10 DUP(0)
Здесь имена byte_array и word_array ссылаются на одну и ту же область памяти.
^ 3. Программная модель процессора Intel Pentium
Для понимания работы команд ассемблера необходимо четко представлять, как выполняется адресация данных, какие регистры процессора и как могут исполь­зоваться при выполнении инструкций. Сейчас мы рассмотрим базовую программ­ную модель процессоров Intel Pentium, в которую входят:

  • 8 регистров общего назначения, служащих для хранения данных и указа­телей;

  • регистры сегментов — они хранят 6 селекторов сегментов;

  • регистр управления и контроля EFLAGS, который позволяет управлять со­стоянием выполнения программы и состоянием (на уровне приложения) процессора;

  • регистр-указатель EIP выполняемой следующей инструкции процессора;

  • система команд (инструкций) процессора;

  • режимы адресации данных в командах процессора.


Начнем с описания базовых регистров процессора Intel Pentium.

Базовые регистры процессора Intel Pentium являются основой для разработки программ и позволяют решать основные задачи по обработке данных. Все они по­казаны на рис. 6.
Регистры общего назначения

31

0










ЕАХ







ЕВХ







ЕСХ







EDX







ESI







EDI







ЕВР







ESP


Сегментные регистры

15

0










CS







DS







ES







SS







FS







GS

Регистры общего назначения

31

0

I

I EFLAGS

Регистры общего назначения

31

0

I

IEIP

Рис. 6. Базовые регистры процессора Intel Pentium
Среди базового набора регистров выделим отдельные группы и рассмотрим их назначение. Начнем с 32-разрядных регистров общего назначения (ЕАХ, ЕВХ, ЕСХ, EDX, ESI, EDI, EBP, ESP), которые могут использоваться в качестве:

  • операндов в арифметических и логических операциях;

  • операндов при вычислении адресов операндов;

  • указателей на переменные в памяти.

Несмотря на то что любой из этих регистров можно использовать для выше­перечисленных операций, необходимо учитывать специфику применения регист­ра ESP — он служит для хранения указателя стека, поэтому задействовать его для других целей не рекомендуется. Во многих программах требуется хранить в реги­страх определенные значения операндов в процессе выполнения каких-либо опе­раций. Для этого подходят регистры ЕСХ, ESI и EDI. Если при этом используется отдельный сегмент данных, то некоторые команды ассемблера предполагают, что переменная, адресуемая одним из этих регистров, находится в сегменте данных, определяемом регистром DS.

Во многих случаях регистры общего назначения используются для предопре­деленных целей:

  • ЕАХ выполняет функцию аккумулятора при работе с операндами и хранит результат операции;

  • ЕВХ — указатель на данные, находящиеся в сегменте данных, адресуемом ре­гистром OS;

  • ЕСХ — счетчик циклов и элементов при строковых операциях;

  • EDX — указатель на порты устройств ввода-вывода;

  • ESI — указатель на данные, находящиеся в сегменте, адресуемом регист­ром DS (при выполнении строковых операций содержит смещение строки-источника);

  • EDI — указатель на данные, находящиеся в сегменте, адресуемом регистром ES (при выполнении строковых операций содержит смещение строки-при­емника);

  • ESP содержит указатель стека в сегменте стека, адресуемом регистром SS;

  • ЕВР содержит указатель на данные, находящиеся в стеке, адресуемом реги­стром SS.

Младшие 16 бит 32-разрядных регистров общего назначения могут адресо­ваться так же, как и 16-разрядные регистры в процессорах 8086 с именами АХ, ВХ, СХ, DX, BP, SI, DI, SP. В свою очередь, 16-разрядные регистры АХ, ВХ, СХ и DX позволя­ют обращаться отдельно как к старшим 8-разрядным регистрам (АН, ВН, СН, DH), так и к младшим (AL, BL, CL, DL). Это проиллюстрировано рис. 7.

Сегментные регистры (CS, DS, SS, ES, FS и GS) содержат 16-разрядные селекто­ры сегментов. Селектор представляет собой специальный указатель, который идентифицирует данный сегмент в памяти. Более подробно мы остановимся на использовании сегментных регистров в главе 4.


31

16 15 87 0

31 бит

ЕАХ

ЕВХ

ЕСХ

EDX

ESI

EDI

ЕВР

ESP

16 бит

АХ

ВХ

СХ

DX

вбит







АН

AL

AH/AL







ВН

BL

BH/BL







СН

CL

CH/CL







DH

DL

DH/DL







SI










DI










ВР










SP




Рис. 7. Использование регистров общего назначения
Помимо регистров общего назначения и сегментных регистров, как мы знаем, в базовой архитектуре имеется еще два регистра: регистр управления/состояния EFLAGS и регистр-указатель адреса следующей инструкции EIP. Рассмотрим их более подробно.



Рис. 8. Регистр управления/состояния процессора




Регистр EFLAFS, часто именуемый регистром флагов, имеет 32 разряда и содер­жит группу битов или, как их чаще называют, флагов состояния, управляющий флаг и группу системных флагов. На рис. 8 показана структура регистра флагов и приводится расшифровка наиболее часто используемых флагов.

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

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

  • DF (флаг направления) используется командами обработки строк. Если DF = 0, строка обрабатывается в прямом направлении, от меньших адресов к большим. Если DF = 1, обработка строк ведется в обратном направлении;

  • SF (флаг знака) показывает знак результата операции, при отрицательном результате SF = 1;

  • ZF (флаг нуля) устанавливается в 1, если результат операции равен 0;

  • AF (флаг вспомогательного переноса) используется в операциях над упако­ванными двоично-десятичными числами. Этот флаг служит индикатором переноса или заема из старшей тетрады (бит 3);

  • PF (флаг четности) устанавливается в 1, если результат операции содержит четное число двоичных единиц;

  • CF (флаг переноса) показывает, был ли перенос или заем при выполнении арифметических операций.

Из всех этих флагов только флаг переноса CF может устанавливаться или сбрасываться непосредственно при помощи команд ассемблера stc, clc и erne. Кроме того, в этот флаг может быть скопирован, бит, определенный командами bt, bts, btr и btc.

Флаги состояния также используются при анализе операций, результатами которых являются безнаковые целые числа, целые числа со знаком и упакован­ные (BCD) целые числа. Если результатом операции является беззнаковое целое число, то установка флага переноса CF в 1 (перенос или заем) свидетельствует о выходе за пределы допустимого диапазона. Если результатом операции являет­ся целое число со знаком (двоичное дополнение числа), то об этом свидетельст­вует установка в 1 флага переполнения OF.

В случае если результат операции интерпретируется как число в формате BCD, то установка флага AF свидетельствует о возникновении переноса или заема. Флаг SF указывает на знак результата, являющегося знаковым числом. Флаг ZF указывает на равенство нулю знакового или беззнакового числа.

При выполнении операций целочисленной арифметики с повышенной точно­стью флаг переноса CF используется командами adc (сложение с переносом) и sbb (вычитание с заемом) для того, чтобы учитывать перенос при переходе к следую­щей операции сложения или вычитания.

Флаги состояния используются командами условного перехода jCC (CC — код условия: eq, le, It, ne и т. д.), командами setCC, ToopCC и cmovCC.

Флаги состояния процессора могут быть помещены в стек и извлечены из сте­ка командами pushf, pushfd, popf, popfd. Кроме того, флаги могут быть загружены в старшую половину регистра АХ или извлечены из старшей половины при помо­щи команды lahf или sahf.

Перейдем к описанию регистра EIP — он содержит смещение в программном сегменте следующей выполняемой команды. Если в программе встречаются ко­манды jCC, call, ret или iret, то содержимое регистра EIP может измениться про­извольным образом — смещение следующей команды может быть как положи­тельным, так и отрицательным. Содержимое регистра-указателя следующей команды не может быть изменено какой-либо инструкцией напрямую, хотя мож­но получить его содержимое, если выполнить команду call, а затем прочитать указатель на следующую команду, находящийся в стеке.

Регистр EIP можно модифицировать, опять-таки не прямо, а через стек, за­менив адрес следующей команды. Естественно, перед этим следует выполнить команду call.

Прежде чем приступить к анализу команд ассемблера и способов обработки данных, нам необходимо рассмотреть модели памяти, с которыми может работать процессор. Модель памяти определяет способ организации программ и данных в памяти компьютера. В 32-разрядной архитектуре процессора Intel Pentium используются три модели памяти:






  • Рис. 9. Линейная модель памяти

    плоская, или линейная, модель памяти (flat memory model) — память пред­ставляет собой непрерывное пространство адресов. Такое пространство ад­ресов называется линейным. Программный код, данные, область стека рас­полагаются в этом пространстве адресов.

  • сегментированная модель памяти (segment memory model) – память состоит из трех отдельных пространств адресов, которые называются сегментами. При этом программный код, данные и стек размещаются в от­дельных сегментах памяти. Для того чтобы обратиться к байту в памяти, программа формирует логический адрес, состоящий из адреса сегмента (селектора сегмента) и смещения. Программы, выполняющиеся в 32-раз­рядном режиме, могут использовать до 16 383 сегментов разного размера, каждый из которых может иметь размер 232 байт. Схема адресации для сег­ментированной модели памяти показана на рис. 10.



Рис. 9. Сегметированая модель памяти
Механизм преобразования адресов при использовании сегментированной модели таков: вначале все адреса сегментов, определенных в программе, отображаются на общее линейное пространство адресов, доступное процес­сору. Затем логический адрес операнда в памяти преобразуется в линей­ный адрес из пространства адресов. Все эти преобразования прозрачны для работающей программы. Подобная модель позволяет повысить надежность работы программ. Например, если разместить программный код и область стека в разных сегментах, то в случае резкого увеличения размера стека не произойдет перекрытия программного кода данными из стека;


  • модель реального режима адресации (real-address mode memory model) — это модель памяти, используемая в процессорах 8086. Данная модель памя­ти поддерживается для того, чтобы обеспечить совместимость с ранее раз­работанными 16-разрядными приложениями. В этой модели применяется механизм сегментации, причем максимальный размер сегмента не превы­шает 64 Кбайт. Максимальный размер линейного адресного пространства, доступного в этом режиме, равен 220 байт.


При разработке 32-разрядных программ на языке ассемблера обычно исполь­зуется линейная, или плоская, модель памяти. Все примеры 32-разрядных проце­дур, приведенные в этой и последующих главах, разработаны с использованием этой модели. При 32-разрядной адресации операндов логический адрес состоит из 16-разрядного селектора сегмента и 32-разрядного смещения. При 16-раз­рядной адресации логический адрес состоит из 16-разрядного селектора сегмента и 16-разрядного смещения.

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

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

Для четкого понимания того, как осуществляется адресация данных, проана­лизируем способ образования адреса операнда. Адрес операнда формируется по схеме сегмент: смещение. В зависимости от используемой модели памяти адрес переменной в памяти может формироваться как 16 : 16 или 16 : 32. Смещение операнда называется его эффективным или исполнительным адресом (Effective Address, EA).

Селектор сегмента можно указать явным или неявным образом. Обычно селек­тор сегмента загружается в сегментный регистр, а сам регистр выбирается в зави­симости от типа выполняемой операции, как показано в табл. 2.

Таблица 2. Критерии выбора сегментного регистра

^ Тип операции
Команды процессора
Обращение к стеку


Локальные данные
Строки-приемники

Регистр сегмента

CS
SS

DS
ES

Сегмент
Программный сегмент
Сегмен

т стека
Сегмент данных
Сегмент данных адресуемый регистром ES

Описание
Используется при вызовах команд процессора
Используется во всех операциях со стеком, а также в операциях с памятью, в которых базовыми являются регистры ESP и ЕВР

Используется во всех операциях с данными, исключая те, в которых применяется стек или строка-приемник при выполнении строковых операций

Операнд-приемник в строковых операциях


Процессор автоматически выбирает сегмент в соответствии с условиями, опи­санными в табл. 2. При сохранении операнда в памяти или загрузке из памяти в качестве сегментного регистра по умолчанию используется DS, но можно и яв­ным образом указать сегментный регистр, применяемый в операции. ' Пусть, например, требуется сохранить содержимое регистра ЕАХ в памяти, адресуемой сегментным регистром ES и смещением, находящимся в регистре ЕВХ. В этом случае можно использовать команду
mov ES:[EBX]. EAX

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

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

  • для сегмента программного кода — все команды используют исключитель­но сегментный регистр CS;

  • при выполнении строковых операций строка-приемник адресуется только регистром ES;

  • Операции помещения в стек и извлечения из стека всегда используют ре­гистр SS.

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

movDS. BX

Здесь селектор сегмента, находящийся в регистре ВХ, помещается в сегмент­ный регистр DS. В некоторых случаях селектор сегмента может определяться че­рез 48-разрядный указатель, находящийся в памяти. При этом младшее двойное слово содержит 32-разрядное смещение, а старшее слово — 16-разрядный селек­тор сегмента.

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

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

  • смещения, представляющего собой 8-, 16- и 32-разрядное значение;

  • базы, представляющей собой содержимое одного из регистров общего на­значения;

  • индекса, представляющего собой содержимое одного из регистров общего назначения;

  • масштабного множителя, равного 2, 4 или 8.

Эффективный адрес, в общем случае, представляет собой сумму смещения, базы и индекса, причем эта сумма может быть скорректирована с помощью масштабно­го множителя. Схематически это можно представить так, как показано на рис. 11.



Рис. 11. Схема вычисления эффективного адреса (ЕА)
Существуют определенные ограничения, касающиеся применения регистров общего назначения в качестве базовых или индексных при формировании эф­фективного адреса:

  • регистр ESP нельзя использовать в качестве индексного регистра;

  • если в качестве базового используется регистр ESP или ЕВР, то сегментным регистром будет SS. Во всех остальных случаях сегментным регистром по умолчанию является DS.

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

Вариант 1. Для формирования эффективного адреса используется только смещение. Такую адресацию называют прямой. При этом способе адресации эф­фективный адрес берется прямо из поля смещения команды и никакие регистры для его вычисления не привлекаются. Этот режим служит для обращения к про­стым переменным, как показано в примере
mov AX. Meml
Здесь meml — операнд в памяти. Как операнд-источник, так и операнд-приемник должны иметь одинаковый размер, иначе в процессе компиляции будет выдана ошиб­ка. Так, в нашем примере подразумевается, что переменная meml определена как сло­во. Если, например, операнд в памяти является двойным словом, то в команде нуж­но явным образом указать старшую или младшую часть с помощью оператора PTR:
mov AX, word ptr meml
Предположим, что переменная meml определена как двойное слово. Тогда по­казанная ранее команда поместит в регистр АХ значение lD7Fh (рис. 12).



Рис. 12. Размещение переменной meml в памяти

Если нужно сохранить в регистре АХ значение старшего слова переменной meml, то следует применить команду
mov AX. word ptr meml+2
В этом случае в регистр АХ помещаются старшие два байта переменной meml (см. рис. 12), после чего АХ будет содержать значение 0EC34h (обратите внима­ние на порядок расположения байтов!).

Остановимся более подробно на операторе PTR. В общем случае этот оператор можно представить в виде
тип PTR выражение
При помощи оператора PTR переменная или метка, задаваемая выражением, может трактоваться как переменная или метка указанного типа. Тип может быть задан одним из имен или значений, показанных в табл.
Таблица 3. Атрибуты оператора PTR

Тип

BYTE

WORD

DWORD

QWORD

TBYTE

NEAR

FAR

Значение

1

2

4

8

10

OFFFFh

OFFFEh


Выражение может включать в себя любые операнды. Типы BYTE, WORD, DWORD, QWORD и TWORD могут быть использованы только с операндами памяти, а типы NEAR и FAR — только с метками. Если PTR не используется, то ассемблер подразумевает умалчиваемый тип ссылки. Кроме того, оператор PTR служит для организации доступа к объекту, который при другом способе привел бы к ошибке компиляции (например, для доступа к старшему байту переменной размера WORD).

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

Рассмотрим пример программного кода
lea BX. Meml

mov АХ. [ВХ]
В этом примере meml — переменная в памяти размером в слово. Первая ко­манда загружает адрес переменной в регистр ВХ, а вторая помещает в регистр АХ значение, содержащееся по адресу, который находится в ВХ. Работу этого фраг­мента кода иллюстрирует рис. 13.



Рис. 13. Схема косвенной адресации
Предположим, что переменная meml размером в слово имеет значение lA9Fh и занимает два байта в памяти с адресами lCD6h (младший байт) и 1CD7 (стар­ший байт). После выполнения первой команды в регистре ВХ будет находиться адрес переменной meml, являющийся одновременно и адресом первого элемента. Вторая команда помещает в регистры АХ значение переменной meml.

Вариант 3. Для формирования эффективного адреса операнда используется содержимое базового регистра плюс смещение («база + смещение»). Такой вари­ант адресации удобен в двух случаях:

  • при доступе к элементам массива, размер которых не кратен 2. В этом слу­чае базовый регистр содержит адрес массива, а смещение позволяет полу­чать доступ к произвольному элементу массива;

  • при доступе к полям записей или структур. При этом базовый регистр со­держит адрес начала записи или структуры, а смещение определяет эле­мент, к которому нужно получить доступ. Отдельный, но очень важный случай применения этого варианта — извлечение параметров процедуры из стека посредством регистра ЕВР, который служит базовым. При этом пара­метры извлекаются из стека по фиксированным смещениям.

Основное применение базовой адресации — получение доступа к элементам строк и массивов, когда известен начальный адрес данных, а смещение вычис­ляется в процессе выполнения программы. В макроассемблере MASM можно использовать одну из форм записи:
[база + смещение]

[база][смещение]
Здесь база — регистр, содержащий базовое значение адреса, а смещение — значе­ние, которое определяет позицию элемента данных. Вот пример базовой адресации:
si DB "String l"

lea EBX. si

mov AL. byte ptr [EBX][5]
Здесь первая команда (lea EBX. si) помещает в регистр EBX адрес строки, кото­рый одновременно является и адресом первого элемента (имеющего индекс 0). Во время выполнения второй команды к содержимому регистра ЕВХ прибавляется значение 5, указывая на 6-й по порядку элемент строки si (это символ д), после чего значение этого символа помещается в регистр AL. Таким образом, после вы­полнения второй команды регистр AL будет содержать символ д. Алгоритм выпол­нения этого фрагмента программного кода показан на рис. 14.



Рис. 14. Схема базовой адресации
Вариант 4. В следующем режиме эффективный адрес формируется по прин­ципу «индекс + смещение». Смещение при таком способе адресации указывает на начало массива чисел или строки, а индексный регистр содержит номер элемента данных. Например, в показанном ниже фрагменте программного кода в регистр AL помещается элемент строки si с индексом 10 (11-й элемент строки, символ +):
si DB "!@#$%^&*()+]["

mov EBX. 10

mov AL. byte ptr si[EBX]
Вариант 5. В следующем режиме эффективный адрес формируется, по принципу «(индекс х множитель) * смещение». Множитель обычно используется для доступа к элементам, имеющим размер, кратный 2, например к словам, двойным словам и т. д. Смещение при таком способе адресации указывает на начало мас­сива чисел или строки, а индексный регистр содержит номер элемента данных. Далее показан пример, который демонстрирует этот способ адресации:
Sl DB "0123456789ABCDEF"

mov EBX. 7

mov AL. byte ptr sl[EBX*2]
При указанном значении регистра ЕВХ в регистр AL будет помещен символ Е, поскольку он находится по смещению 14 (7 х 2) в строке sl.

Вариант 6. В следующем режиме эффективный адрес формируется по прин­ципу «база + индекс + смещение». Такой способ адресации обычно используется для адресации элементов в двухмерных массивах данных или для доступа к от­дельным элементам в массивах, содержащих записи. Проанализируем фрагмент программного кода, в котором применяется данный способ адресации:
Sl DB "ABCD EFGH IJKLM"

s2 DB "abed efgh ijklm"

S3 DB "0123 4567 B9"
sarray label dword

DD sl

DD s2

DD S3

. . .

mov EBX. sarray+4

mov ESI. 10

mov AL. byte ptr [EBX][ESI][2]

. . .
Здесь в сегменте данных определен массив строк sarray, содержащий адреса строк sl - s3. В каждой строке определены группы элементов, разделенные сим­волом пробела. Предположим, нужно получить доступ к символу к, находящему­ся в строке s2. Будем использовать регистр ЕВХ как базовый, а регистр ESI как индексный. Поместим в ЕВХ адрес строки s2> где находится искомый элемент (ко­манда mov ЕВХ. sarray+4), а в регистр ESI — смещение группы элементов, в которой находится символ к (величина смещения в данном случае равна 10). Для этого выполним команду
mov ESI. 10
Символ к находится по смещению 2 относительно группы элементов ijklm, по­этому последняя команда помещает символ в регистр AL:
mov AL. byte ptr [EBX][ESI][2]
Вариант 7. В последнем режиме эффективный адрес формируется по принципу «база + (индекс х множитель) + смещение». Такой способ адресации обычно требуется для адресации элементов в двухмерных массивах данных, когда нужно полу­чить доступ к словам, двойным словам или учетверенным словам. Проанализируем фрагмент программного кода, в котором применяется данный способ адресации:
al DD 45. -87. 23. -11. 83. -442. 56. -340 а2 DD 92. -31. 9. -598. 361. 406. -172. 7 аЗ DD 234. 8. -177. 921. 380. -12. 0. -51 iarray label dword

DD al

DD a2

DD a3

mov EBX. iarray+8

mov ESI. 4

mov EAX. [EBX][ESI*2][8]
Здесь определены три массива целых чисел (al - аЗ), состоящих из двухслов­ных элементов. Предположим, требуется поместить число 380 (выделенное жир­ным шрифтом) в регистр ЕАХ. Для этого воспользуемся несколько искусственной схемой, которая поможет понять суть этого метода адресации.

В регистр ЕВХ поместим адрес массива аЗ (команда mov EBX. iarray+8), в кото­ром находится искомое число. Таким образом, регистр ЕВХ будет использоваться как базовый. Регистр ESI будет выступать в качестве индексного, куда мы поме­стим значение 4 (размер двойного слова в байтах) с помощью команды
mov ESI. 4
Наконец, последняя команда загружает искомый элемент массива аЗ (380) в регистр ЕАХ:
mov EAX. [EBX][ESI*2][8]
В этой команде выражение [ESI*2], равное 8, указывает на элемент массива аЗ с индексом 2 (то есть число -177), а выражение [В] определяет смещение на 8. В результате суммирования всех значении (ЕВХ, ESI, В) получаем эффективный адрес (ЕА) искомого элемента.

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

Хочу сделать важное замечание: все семь рассмотренных вариантов адресации проверены на компиляторе MASM версии 7.10 из пакета Windows XP DDK.

Рассмотрим еще один способ адресации данных в памяти, который использу­ется в ряде случаев и называется непосредственной адресацией. При этом спосо­бе адресации операнд задается непосредственно в инструкции. Например, сле­дующая команда вычитает значение 20 из регистра ЕАХ:
sub EAX. 20
Все арифметические команды, за исключением команд div и idiv, допускают непосредственную адресацию. Максимальное значение непосредственного операн­да варьируется для разных команд, однако в любом случае не может превышать зна­чения, которое может принимать операнд размером в двойное слово без знака (2:и).

Последний способ адресации, который мы проанализируем, — регистровая адресация. При регистровой адресации операнд находится в регистре общего на­значения, а в некоторых случаях — в сегментном регистре. Если команда имеет два операнда, то в большинстве случаев они могут быть регистрами. Вот примеры регистровой адресации:
mov EAX. EDX

add EAX. ECX
Оба операнда должны иметь одинаковую размерность. Следующая команда вызовет ошибку:
mov EAX. BL
Здесь оба операнда — регистры ЕАХ и BL — имеют разную размерность, поэтому компилятор выдаст ошибку при трансляции этой команды.

Рассмотрим вкратце команды общего назначения процессора Intel Pentium. Более детальный анализ всех групп команд мы будем проводить в следующих главах, когда будут рассматриваться практические аспекты применения языка ассемблера. Команды общего назначения (general-purpose instructions) по функ­циональному признаку можно разделить на несколько групп:

  • команды перемещения (пересылки, передачи) данных;

  • команды целочисленной арифметики (сложения, вычитания, умножения и деления);

  • команды логических операций;

  • команды передачи управления (условных и безусловных переходов, вызо­вов процедур);

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

1   2   3   4   5   6   7   8   9   ...   41

Похожие:

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций для студентов заочной формы обучения направления 080201 (Информатика)
Предлагаемый конспект лекций представляет собой пособие по предмету “Теория информации”, который читается в Сумском государственном...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций 2007 Экология. Конспект лекций. Для студентов специальностей...
Экология. Конспект лекций. Для студентов специальностей 080201 «Информатика», 090220 «Оборудование химических производств и предприятий...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине информационные и телекоммуникационные...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине “
«Компьютерная инженерия», специальности 091501 «Компьютерные сети и системы», 091502 «Системное программирование»

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по курсу Выбранные вопросы информатики (часть 2)...
Точно так же как художник может выбирать для рисования различные инструменты, программист, создающий аплет Java, может выбирать различные...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине “Статистика в машиностроении ” для студентов специальности
Конспект лекций предназначен для самостоятельного изучения студентами теоретической части курса “ Статистика в машиностроении ” (для...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по дисциплине “ основы защиты информации” для направления...
Министерство образования и науки украины восточноукраинский государственный университеТ

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

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций и методические указания к выполнению контрольной работы к изучению курса
Конспект лекций и методические указания к выполнению контрольной работы по курсу “Проектирование специальных станочных и контрольных...

Конспект лекций по курсу Системное программирвание для специальности Информатика Лекция 1 iconКонспект лекций по курсу «Организация производства»
Конспект лекций по курсу «Организация производства» (для студентов и слушателей заочной формы обучения фпоизо специальностей 050100...

Вы можете разместить ссылку на наш сайт:
Школьные материалы


При копировании материала укажите ссылку © 2013
контакты
uchebilka.ru
Главная страница


<