Скачать 1.23 Mb.
|
Рис. 1.3. Формирование физического адреса В примере предполагается, что сегмент данных, адресуемый через регистр DS, имеет базовый адрес lDE20h, а ячейка meml расположена в байтах 6 и 7 этого сегмента (смещение meml относительно начала сегмента равно 6). Поскольку младшая 16-ричная цифра базового адреса сегмента должна быть равна 0, сегмент всегда начинается с адреса, кратного 16, т.е. на границе 16-байтового блока памяти (параграфа). Число, хранящееся в сегментном .регистре, называют сегментным адресом. Следует помнить, что сегментный адрес в 16 раз меньше физического; его можно рассматривать, как номер параграфа, с которого начинается данный сегмент. Регистр CS обеспечивает адресацию к сегменту, в котором находятся программные коды, регистры DS и ES - к сегментам с данными (таким образом, в любой момент времени программа может иметь доступ к 128 Кбайт данных), а регистр SS -к сегменту стека, который на машинах типа IBM PC, в отличие от других вычислительных систем, может быть очень большим и достигать 64 Кбайт. Сегментные регистры, естественно, не могут выступать в качестве регистров общего назначения. Указатель команд IP "следит" за ходом выполнения программы, указывая в каждый момент относительный адрес команды, следующей за исполняемой. Регистр IP программно недоступен (IP - это просто его сокращенное название, а не мнемоническое обозначение, используемое в языке программирования); наращивание адреса в нем выполняет микропроцессор, учитывая при этом длину текущей команды. Команды переходов, прерываний, вызова подпрограмм и возврата из них изменяют содержимое IP, осуществляя тем самым переходы в требуемые точки программы. Регистр флагов, эквивалентный регистру состояния процессора других вычислительных систем, содержит информацию о текущем состоянии процессора (рис. 1.4). Он включает 6 флагов состояния и 3 бита управления состоянием процессора, которые, впрочем, тоже называются флагами. 15 14 13 12 11 10 09 08 07 06 05 04 03 02 01 00 Разряды
Рис. 1.4. Регистр флагов. Флаг переноса CF (Carry Flag) индицирует перенос или заем при выполнении арифметических операций, а также служит индикатором ошибки при обращении к системным функциям. Флаг паритета PF (Parity Flag) устанавливается в 1, если результат операции содержит четное число двоичных единиц. Флаг вспомогательного переноса AF (Auxiliary Flag) используется в операциях над упакованными двоично-десятичными числами. Он индицирует перенос или заем из старшей тетрады (бита 3). Флаг нуля ZF (Zero Flag) устанавливается в 1, если результат операции равен 0. Флаг знака SF (Sign Flag) показывает знак результата операции, устанавливаясь в 1 при отрицательном результате. Управляющий флаг трассировки (ловушки) TF (Trace Flag) используется для осуществления пошагового выполнения программы. Если TF«1, то после выполнения каждой команды процессор реализует процедуру прерывания типа 1 (через вектор, расположенный по адресу 04). Управляющий флаг разрешения прерываний IF (Interrupt Flag) разрешает (если равен 1) или запрещает (если равен 0) процессору реагировать на прерывания от внешних устройств. Управляющий флаг направления DF (Direction Flag) используется командами обработки строк. Если DF-0, строка обрабатывается в прямом направлении, от меньших адресов к большим; если DF*1, обработка строки идет в обратном направлении. Флаг переполнения OF (Overflow Flag) фиксирует переполнение, т.е. выход результата за пределы допустимого диапазона значений. Для работы с регистром флагов предусмотрен ряд команд. Установка и сброс флагов CF, DF и IF осуществляется командами STC, STD и STI (установка) и CLC, CLD и CLI (сброс). Все содержимое регистра флагов можно сохранить в стеке командой PUSHF и извлечь из стека командой POPF; кроме того, младший байт регистра флагов (флаги CF, PF, AF, ZF и SF) можно переслать в регистр АН командой LAHF или загрузить в регистр флагов из АН командой SAHF. Сегментация памяти Перед тем как изучать регистры и команды процессора 8086, необходимо понять, как он адресует память, используя системные сегменты и смещения — термины, часто вызывающие недоразумения. Используя для представления значения адреса 20 бит, 8086-й процессор может иметь прямой доступ к 1 Мбайт памяти. DOS, ROM BIOS и другие находящиеся в памяти программы уже занимают определенное место памяти персонального компьютера, поэтому остальные программы запускаются, используя меньшее пространство памяти — до 640 Кбайт. Если вы хотите, чтобы ваша программа работала на возможно большем числе компьютеров — ограничьте пределы необходимой памяти. Замечание Последние модели процессов, такие как 80386, 80486 и Pentium (известный как 80586), эмулируют режим процессора 8086. Методы, описанные в этой главе, применимы ко всем процессорам 80х86. Программирование на языке ассемблера Независимо от того, сколько памяти может адресовать процессор или сколько микросхем памяти установлено в компьютере, наименьшим блоком памяти является 8-битовый байт. Как отмечалось ранее, каждый байт имеет свое уникальное местоположение, называемое физическим адресом, по которому программы могут читать и записывать информацию. Очевидно, что для адресации больших объемов памяти необходимо большее число бит под физические адреса. Если в вашем компьютере 64 Кбайт памяти, тогда для задания адреса любого байта достаточно 16 бит, с помощью которых представляются значения от 0 до 65535 (216-!), или округленно — 64 Кбайт. Для адресации 1 Мбайт памяти персонального компьютера требуется как минимум 20 бит (220-! равно 1048575, или, в шестнадцатеричном представлении, FFFFF). Проблема состоит в том, что 8086 процессор использует только 16-битовые регистры. Тогда каким образом процессор 8086 может иметь доступ ко всему мегабайту памяти в обычном персональном компьютере? Ответом является сегментация памяти — метод, используемый процессором 8086 для разделения большого адресного пространства памяти на логические 64 Кбайт фрагменты. С помощью этого метода адрес конкретного байта может быть выражен двумя значениями: адресом фрагмента (сегмента) и 16-битовым смещением от начала сегмента. Эта комбинация значений сегмента и смещения называется логическим адресом. Первый байт сегмента имеет смещение 0000, второй — 0001, третий — 0002 и т.д., независимо от того, где сегмент физически начинается в памяти. Рис. 4.1 демонстрирует эту идею, показывая, что каждая точка памяти имеет как физический адрес (справа), так и логический адрес (слева), выраженный через смещение от начала границы сегмента. С помощью сегментации процессор 8086 может эффективно адресовать до 1 Мбайт памяти, даже используя относительно небольшие 16-битовые регистры. Кроме того, сегментация позволяет легко перемещать программы в новые физические области памяти, изменяя только базовый адрес сегмента. При этом не требуется изменять значения смещений внутри сегмента, что позволяет перемещаемым программам исполняться одинаково в разных местах памяти. ![]() Нижняя память Физические адреса Логические адреса
Верхняя память ![]() Сегмент Сегмент Сегмент Сегмент Рис. 1. Логические адреса с соответствующими физическими адресами в памяти Параграфы, сегменты и смещения Для определения начал сегментов памяти процессор 8086 использует четыре 16-битовьк сегментных регистра. Для создания 20-битового физического адреса процессор объединяет значение одного сегментного регистра с 16-битовым смещением (логическим адресом). Это делается путем умножения сегментного значения на 16 (сдвиг влево на 4 бита) и прибавлением к результату смещения (умножение на 16 эквивалентно четырехкратному сдвигу битов влево, как вы помните из главы 3). Исходя из этого получается, что границы сегментов располагаются через каждые 16 байт физических адресов. Каждый из этих 16-байтовых фрагментов называется параграфом. Простые вычисления показывают, что максимально может существовать 65536 параграфов и, следовательно, такое же число границ сегментов в одномегабайтовом адресном пространстве процессора 8086 (1048576/16). (Заметим, что это также равняется числу значений, которые могут быть выражены с помощью одного 16-битового сегментного регистра.) Кроме того, запомните несколько важных сведений о сегментах. • Сегменты физически не выделены в памяти, что является общим заблуждением. Сегменты — это логические окна, через которые программы просматривают области памяти удобными, в 64 Кбайт порциями. ^ • Начальное положение сегмента (т.е. логический адрес) определяется вами и может иметь любое значение от | 0000 до FFFF в шестнадцатеричном представлении. Каждое логическое значение сегмента (0,'1, 2,..., 65535), соответствует физической границе параграфа (0,16, 32,..., 1048560). • Размеры сегментов могут изменяться от 16 байт до 64 Кбайт (65536 байт). Действительный размер сегмента определяется вами и вашей программой. • Сегменты не обязательно располагаются физически в памяти один за другим, хотя так бывает достаточно часто. • Сегменты могут перекрываться один другим; поэтому один и тот же байт в памяти может иметь различные логические адреса, определяемые разными, но при этом эквивалентными парами сегмент-смещение. Но, несмотря на это, каждый байт имеет только единственный 20-битовый физический адрес. Почти всех, кто впервые знакомится с сегментацией памяти, этот последний пункт приводит в замешательство. Две разные пары сегмент-смещение могут (и так часто бывает) указывать в памяти на один и тот же байт. Если вы вспомните, как процессор создает 20-битовые физические адреса — умножением значения сегмента на 16 и прибавлением смещения, вы увидите, что шестнадцатеричные значения пар сегмент-смещение 0000:0010 и 0001:0000 указывают на одну и ту же физическую область памяти. Если повторить процесс преобразования этих логических адресов в физические в десятичной системе счисления, то при вычислении (0000х16)+1б и (0001х16)+0 получается один и тот же результат –16. Лекция № 4 Модели памяти и структуры программ Структура и образ памяти программы .ЕХE Программы, выполняемые под управлением MS-DOS, могут принадлежать к одному из двух типов, которым соответствуют расширения имен программных файлов .СОМ и .ЕХЕ. Основное различие этих программ заключается в том, что программы типа .СОМ состоят из единственного сегмента, в котором размещаются программные коды, данные и стек, а в программах типа .ЕХЕ для собственно программы, данных и стека предусматриваются отдельные сегменты. Таким образом, размер программы типа .СОМ не может превысить 64 Кбайт, а размер программы типа .ЕХЕ практически не ограничен, так как в нее может входить любое число сегментов программы и данных. Структура типичной программы типа .ЕХЕ на языке ассемблера выглядит следующим образом. title Программа типа .ЕХЕ text segment 'code' assume CS:text, DS:data mургос proc mov AX,data mov DS, AX ;Текст программы . . . ;Определения данных myproc endp text ends data segment . . . data ends stack segment stack 'stack* dw 128 dup (0) stack ends end myproc Следует заметить, что при вводе исходного текста программы с клавиатуры можно использовать как прописные, так и строчные буквы: транслятор воспринимает, например, строки MOV AX.DATA и mov ax,data одинаково. Однако с помощью соответствующих ключей можно заставить транслятор различать прописные и строчные буквы в именах. Тогда программные строки MYPROC proc и myproc proc уже не будут эквивалентны. В настоящей книге принята следующая система обозначений: - тексты программ набраны строчными буквами, за исключением обозначений регистров (AX, CS) и имен файлов (MYFILE.TXT), которые для наглядности выделены прописными буквами; - в тексте книги (но не в программах) прописными буквами выделены зарезервированные слова, т.е. операторы языка ассемблера (SEGMENT, ENDS, MOV и т.д.), а также имена файлов. Рассмотрим теперь структуру приведенной программы. Оператор TITLE позволяет предпослать программе текстовый заголовок, который будет выводиться на все страницы листинга трансляции. Программа состоит из трех сегментов: сегмента команд, или программного сегмента с произвольным именем text, сегмента данных с именем data и сегмента стека с именем stack (оба эти имени также могут выбираться произвольно). Каждый сегмент открывается оператором SEGMENT и закрывается оператором ENDS. Перед обоими операторами должно стоять имя сегмента. Порядок сегментов в большинстве случаев роли не играет. Слово 'CODE', стоящее в апострофах в строке описания сегмента команд, указывает класс сегмента - "программный". Классы сегментов анализируются компоновщиком и используются им при компоновке загрузочного модуля: сегменты, принадлежащие одному классу, загружаются в память друг за другом. Для простых программ, включающих один сегмент команд и один сегмент данных, эта процедура не имеет значения, однако для правильной работы компоновщика LINK и отладчика CodeView при описании сегмента команд необходимо указание его класса 'CODE'. Текст сегмента команд начинается с оператора ASSUME, который позволяет транслятору сопоставить сегментные регистры и адресуемые ими сегменты. Определение CS:text указывает транслятору, что данный сегмент является программным и будет адресоваться с помощью сегментного регистра CS. Определение DS:data закрепляет за сегментом data сегментный регистр DS, как регистр, используемый по умолчанию, что позволяет ссылаться на переменные, описанные в сегменте data, без явного указания регистра DS. При этом ассемблер проверяет, действительно ли они описаны в сегменте data. Собственно программа обычно состоит из процедур. Деление программы на процедуры не обязательно, но повышает ее наглядность и облегчает передачу управления на подпрограммы и в другие программные модули. В рассматриваемом примере сегмент команд содержит единственную процедуру тургос, открываемую оператором PROC и закрываемую оператором ENDP. Перед обоими операторами указывается имя процедуры. В первых строках программы инициализируется регистр DS - в него заносится сегментный адрес сегмента данных. Поскольку передача в сегментные регистры непосредственных значений не допускается, в качестве "перевалочного пункта" используется регистр АХ. После того, как регистр DS инициализирован, программа может обращаться к данным, описанным в регистре данных. Сегмент данных содержит описания всех переменных, используемых в программе. Способы описания данных будут рассмотрены ниже. Строка описания сегмента стека должна содержать класс сегмента - 'STACK', а также тип объединения - STACK. Тип объединения указывает компоновщику, каким образом должны объединяться одноименные сегменты разных модулей - накладываясь друг на друга (тип объединения COMMON) или присоединяясь друг к другу (тип объединения STACK для сегментов стека или PUBLIC для всех остальных). Хотя для одномодульных программ тип объединения значения не имеет, для сегмента стека обязательно указание типа STACK, поскольку в этом случае при загрузке программы выполняется автоматическая инициализация регистров SS (адресом начала сегмента стека) и SP (смещением конца сегмента стека). В приведенном примере для стека зарезервировано 128 слов памяти. Класс для сегмента стека указывать не обязательно, однако в тех случаях, когда программисту важен фактический порядок расположения сегментов программы в памяти, лучше всем сегментам присвоить какие-то различающиеся классы (один сегмент может не иметь класса). В этом случае компоновщик расположит сегменты в памяти в таком порядке, в котором они следуют в исходном тексте программы. Текст программы заканчивается директивой END, завершающей трансляцию. В качестве операнда этой директивы указывается точка входа в главную процедуру. При загрузке программы сегменты размещаются в памяти, как показано на рис. 2.1. Образ программы в памяти начинается с префикса программного сегмента (Program Segment Prefics, PSP), образуемого и заполняемого системой. PSP всегда имеет размер 256 байтов содержит таблицы и поля данных, используемые системой в процессе выполнения программы. Некоторые из этих полей будут описаны ниже. Вслед за PSP располагаются сегменты программы. Сегментные регистры автоматически инициализируются следующим образом: ES и DS указывают на начало PSP (что дает возможность, сохранив их содержимое, обращаться затем i программе к PSP), CS - на начало сегмента команд, a SS - на начало сегмента стека. В указатель команд IP загружается относительный адрес точки входа в программу (из операнда директивы END), а в указатель стека SP - смещение конца сегмента стека. Таким образом, после загрузки программы в па мять адресуемыми оказываются все сегменты, кроме сегмента данных. Инициализация регистра DS в первых строках программы, позволяет сделать адресуемым и этот сегмент. E ![]() ![]() ![]() CS - - 256 байтов IP ![]() ![]() S ![]() ![]() Рис. 2.1. Образ памяти программы .ЕХЕ. Структура и образ памяти программы .СОМ Как уже отмечалось, программа типа .СОМ отличается от программы типа .ЕХЕ тем, что содержит лишь один сегмент включающий все компоненты программы: PSP, программный код (т.е. оттранслированные в машинные коды программные строки), данные и стек. Структура типичной программы типа •СОМ на языке ассемблера выглядит следующим образом: title Программа типа .СОМ text segment 'code' assume CS:text,DS:text org lOOh myproc proc ; Текст программы … myproc endp … ;Определения данных text ends end myproc Программа содержит единственный сегмент text, которому присвоен класс 'CODE'. В операторе ASSUME указано, что сегментные регистры CS и DS будут указывать на этот единственный сегмент. Оператор ORG lOOh резервирует 256 байт для PSP. Заполнять PSP будет по-прежнему система, но место под него в начале сегмента должен отвести программист. В программе нет необходимости инициализировать сегментный регистр DS, поскольку его, как и остальные сегментные регистры, инициализирует система. Данные можно разместить после программной процедуры (как это показано на рисунке), или внутри нее, или даже перед ней. Следует только иметь в виду, что при загрузке программы типа .СОМ регистр IP всегда инициализируется числом lOOh, поэтому сразу вслед за оператором ORG lOOh должна стоять первая выполнимая строка программы. Если данные желательно расположить в начале программы, перед ними следует поместить оператор перехода на реальную точку входа, например JMP entry. Образ памяти программы типа .СОМ показан на рис. 2.2. После загрузки программы все сегментные регистры указывают на начало единственного сегмента, т.е. фактически на начало PSP. Указатель стека автоматически инициализируется числом FFFEh. Таким образом, независимо от фактического размера программы ей выделяется 64 Кбайт адресного пространства, всю нижнюю часть которого занимает стек. Поскольку верхняя граница стека не определена и зависит от интенсивности и способа использования стека программой, следует опасаться затирания стеком нижней части программы. Впрочем, такая опасность существует и в программах типа .ЕХЕ. CS, DS, ES, SS
<— IP <—— SP=FFFEh Рис. 2.2. Образ памяти программы .СОМ. Лекция № 5 Основные определения данных, констант. Режимы адресации
Для заполнения последовательных байтов, слов или двойных слов памяти, а также для резервирования памяти служат директивы ассемблера (псевдооператоры) DB, DW и DD, а для резервирования массивов - директива DUP: count dw 1000 ; В слово с именем count помещается число 1000 coeffs dw 5,12000,0,168 ; Указанными числами заполняются 4 ; последовательные слова памяти. ; Первому слову дается имя coeffs mask db OFFh ; В байт именем mask помещается 16-ричное ; число FFh mes db --Внимание!--' ; Строка байтов с именем mes заполняется ; указанным текстом addr dw mes ; В слово с именем addr помещается смещение ; первого байта строки mes addrd dd myproc ; В двойное слово с именем addrd помещается ; двухсловный адрес процедуры myproc (в ; первое слово относительный адрес, во ; второе – сегментный адрес) area dw 128 dup (?) ; Резервируется область памяти объемом 128 ; слов testmes db 100 dup ('#') ; Строка с именем testmes заполняется кодом ; символа # array dw 1024 dup (256) ; Массив из 1024 слов заполняется числом 256 Для определения констант служат директива EQU и знак равенства: kilo equ 1024 ; Числу 1024 присваивается символическое имя kilo offs=80*2*12+40*2 ; Константа offs получает значение, равное ; результату вычисления указанного выражения length=OFFFFh ; Числу Ft-"FFh=65535 присваивается ; символическое имя length Отличие директивы equ от знака равенства заключается в том, что директива equ присваивает символическим именам значения "раз и навсегда", а при использовании знака равенства значения констант можно изменять: counter=0 ; Символическое имя counter принимает значение О counter=counter+l ; Символическое имя counter принимает значение 1 Для ссылок на текущую ячейку используется обозначение счетчика текущего адреса $: mes db 'Ждите' mes_1en=$-mes В этом примере константа mes—len получает значение длины строки mes (в данном случае 5 байтов), которая вычисляется как разность значения счетчика текущего адреса после определения строки и ее начального адреса mes. Данные, описанные в программе, должны участвовать в операциях в соответствии со своими описаниями. Ассемблер фиксирует ошибку, если, например, данное, описанное как байт, участвует в операции со словом. Во многих случаях, однако, требуются как раз такие операции. Для их реализации предусмотрен атрибутивный оператор PTR: bits dw OF5E9h ; Данное описано как слово mov AX,bits ; Операция соответствует описанию mov BH.byte ptr bits ; Из слова bits забирается младший ; байт (число E9h) mov CL.byte ptr bits+1 ; Из слова bits забирается старший ; байт (число F5h) addr dd myproc ; Данное описано как двойное слово mov BX.word ptr addr ; Забираем младшее слово(относительный ; адрес myprog) mov ES.word ptr addr+2 ; Забираем старшее слово(сегментный ; адрес myprog) 2. Режимы адресации Режимом, или способом адресации называют процедуру нахождения операнда. Различают следующие режимы адресации. 2.1. Регистровый. Операнд (байт или слово) находится в регистре. Этот способ адресации применим ко всем программно- адресуемым регистрам процессора. inc СХ ; Увеличение на 1 содержимого АХ push OS ; Сегментный адрес сохраняется в стеке xchg ВХ.ВР ; Регистры ВХ и ВР обмениваются содержимым mov ES.AX ; Содержимое АХ пересылается в ES 2.2. Непосредственный. Операнд, (байт или слово) указывается в команде; он может иметь любой смысл (число, адрес, код ASCII), а также быть представлен в виде символического обозначения. mov AH,40h ; Число 40h загружается в АН mov AL,'*' ; Код ASCII символа * загружается в AL int 21h ; Команда прерывания типа 21h limit equ 523 ; Число 528 получает обозначение limit mov CX,limit ; Число, обозначенное limit, загружается ; в CX Важным применением непосредственной адресации является пересылка относительных адресов (смещений). Чтобы указать, что речь идет об относительном адресе данной ячейки, а не об ее содержимом, используется описатель OFFSET: ; Сегмент данных mes db 'Ждите' ; Отрока символов ; Сегмент команд mov DX,offset mes ; Адрес строки засылается в ОХ В приведенном примере относительный адрес строки mes, т.е. расстояние в байтах первого байта этой строки от начала сегмента; в котором она находится, заносится в регистр DX. 2.3. Прямой. Адресуется память; адрес ячейки памяти (слова или байта) указывается в команде: ;Сегмент данных mem dw 0 ; Резервируется слово памяти (и в него ; засылается 0) ;Сегмент команд Inc mem ; Содержимое этого слова увеличивается на 1 mov DX.mem ; Содержимое слова с именем mem загружается ; в регистр DX Строго говоря, процессору следует передать информацию о том, с помощью какого сегментного регистра определять адрес: inc DS:mem mov OX,DS:mem Однако, как уже отмечалось, по умолчанию все смещения вычисляются относительно DS, поэтому в данном случае это указание сегментного регистра избыточно. В тех же случаях, когда рассматриваемая ячейка находится в сегменте, адресуемом через какой-либо другой сегментный регистр (ES, CS или SS), указание сегментного регистра является обязательным: Inc ES:meml Часто бывает нужно обращаться к памяти по известному абсолютному адресу. В этом случае указание сегментного регистра обязательно: mov AL,DS:17h ; Загрузка AL из ячейки с адресом 17h ; относительно DS mov BX,ES:2Ch ; Загрузка ВХ из ячейки с адресом 2Сh ; относительно ES При обращении по абсолютным адресам константа, определяющая адрес, может быть заключена в квадратные скобки. Приведенные ниже команды эквивалентны предыдущим: mov AL,DS:[17h] mov BX,ES:[2Ch] Следует подчеркнуть, что при любом обращении к памяти процессор обязательно использует один из сегментных регистров, Перед выполнением команды обращения к памяти в используемый сегментный регистр следует заслать требуемый сегментный адрес. Пусть, например, мы хотим прочитать код символа, изображаемого в настоящий в первой позиции экрана. Известно, что текстовый видеобуфер начинается с адреса B8OOOh. Для того, чтобы настроить на этот адрес сегментный регистр, в него следует загрузить число, характеризующее номер параграфа, с которого начинается видеобуфер, т.е. B8000h/16=B800h: mov AX,OB800h ; Сегментный адрес видеобуфера mov ES.AX ; отправим в ES mov AL,ES:[0] ; Прочитаем первый байт видеобуфера ^ Адресуется память (байт или слово). Относительный адрес операнда находится в регистрах ВХ или ВР (базовая адресация) или в регистрах SI или DI (индексная адресация). При использовании регистров ВХ, SI и DI подразумевается сегмент, адресуемый через DS; при использовании ВР подразумевается сегмент стека и, соответственно, регистр SS. Допускается замена сегмента. Обозначение этого способа адресации: [ВХ](подразумевается DS:[BX]) [ВР](подразумевается SS:[BP]) [Sl](подразумевается DS:[SI]) [DI](подразумевается DS:[DI]) Регистровый косвенный способ адресации удобно использовать в тех случаях, когда к некоторой ячейке памяти приходится обращаться многократно: mov SI,offset celts ; Относительный адрес ячейки cells ; загружается в SI mov AX,[SI] ; Содержимое ячейки cells ; ; загружается в AX inc [SI] ; инкремент содержимого ячейки ; cells mov BX,[SI] ; новое содержимое ячейки cells ; ; загружается в BX ^ Адресуется память (байт или слово). Относительный адрес операнда определяется как сумма содержимого регистра BX, BP, SI или DI и указанной в команде константы, называемой смещением. Смещение может быть числом или адресом. При использовании регистров BX, SI и DI подразумевается сегмент, адресуемый через DS; при использовании BP подразумевается сегмент стека – регистр SS. Допускается замена сегмента. Обозначение этого способа адресации: смещение [BX] (подразумевается DS: смещение [BX]) смещение [BP] (подразумевается SS: смещение [BP]) смещение [SI] (подразумевается DS: смещение [SI]) смещение [DI] (подразумевается DS: смещение [DI]) Допустимы также обозначения (со всеми регистрами) вида: [BX]+ смещение [BX+ смещение] Пусть в сегмента данных определен массив из 10 чисел: array db 0,10,20,30,40,50,60,70,80,90 |
![]() | Анализ к ф. м н., доцент Рудой Евгений Михайлович 2013-2014 уч год Лекция (2 часа) Введение. Нормированные пространства. Компактные множества. Теорема Хана-Банаха | ![]() | Лекция введение Материалы данного файла могут быть использованы без ограничений для написания собственных работ с целью последующей сдачи в учебных... |
![]() | Лекция «Сущность и проблемы вэд, состояние вэд в России» 1 час. 2... Лекция «Внешнеэкономические операции и сделки: виды, классификация, организация» 1 час | ![]() | Лекция 1 введение Петрофизика сформировалась к началу 60-х годов, когда появились обобщающие труды по всем вопросам изучения физических свойств пород... |
![]() | 1. Лекция: Введение. История, предмет, структура информатики Хотя информатика и считается достаточно молодой наукой по отношению ко многим другим отраслям знания, но предпосылки к ее зарождению... | ![]() | Лекция №1. Введение в Экономикс. Основная проблема экономики и производственные... Под материальными потребностями подразумевается желания потребителей приобрести и использовать товары и услуги, которые доставят... |
![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок | ![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок |
![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок | ![]() | Лекция №1 Лекция № Общие принципы эффективной организации учебного процесса. Физиологическая цена учебных нагрузок |