3. Способы адресации памяти. Ввод и вывод строки функциями 09h и 0Аh прерывания 21h.

3. Способы адресации памяти. Ввод и вывод строки функциями 09h и 0Аh прерывания 21h

Цель работы:  приобретение навыков в составлении простых программ, содержащих ввод данных и вывод результатов; получение знаний о режимах адресации микропроцессора i8088, о выполнении и отладке программ на ЭВМ.

Теоретическая часть

Режимы адресации микропроцессора i8088

Микропроцессор (МП) i8088 может использовать различные режимы адресации для получения доступа к данным, которыми должна оперировать программа. Ассемблер определяет режим на основе формата операнда в исходной программе.

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

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

При регистровой адресации МП извлекает операнд из регистра или загружает его в регистр. Например,

mov ax, cx          ; пересылка содержимого регистра cx в регистр ax

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

mov cx, 500        ; загрузить в регистр cx значение 500

Для описания других режимов адресации введем понятие исполнительного адреса.

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

При прямой адресации исполнительный адрес является составной частью команды. МП добавляет этот адрес к сдвинутому на 4 бита (т.е. умноженому на 16) содержимому регистра сегмента данных DS и получает 20–битовый физический адрес операнда. Обычно прямая адресация применяется, если операндом служит метка (символический адрес). Например,

mov ax, table ;загрузка в регистр ax содержимого
;ячейки памяти (2 байта) с меткой table

При косвенной регистровой адресации исполнительный адрес операнда содержится в базовом регистре bx, регистре указателя базы bp или в индексном регистре si или di. Регистровые операнды косвенной адресации необходимо заключать в квадратные скобки. Например,

mov ax, [bx] ;загрузить в регистр ax содержимое ячейки,
;исполнительный адрес, которой находится в
;регистре bx

Чтобы поместить смещение (относительный адрес) ячейки table в регистр bx, можно использовать директиву OFFSET. Например,

mov bx, offset table ;поместить в регистр bx смещение
;ячейки table
;регистре bx

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

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

mov ax, [bx]+4    ;загрузить в регистр ax содержимое по адресу,
mov ax, [bx+4]    ;отстоящему на 4 байта от ячейки, исполнительный
mov ax, 4[bx]      ;адрес которой находится в регистре bx

При прямой адресации с индексированием исполнительный адрес вычисляется как сумма значений сдвига и индексного регистра si или di. Этот тип адресации удобен для доступа к элементам таблицы, когда сдвиг указывает на начало таблицы, а индексный регистр – на ее элемент. Например,

mov di, 2
mov al, table[di]
;загрузить в al третий элемент
; (со смещением 2) таблицы table

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

mov ax, [bx+2+di]
mov ax, [bx+2][di]
mov ax, [bx][di+2]

При всех способах адресации (кроме тех, где используется регистр bp) исполнительный адрес вычисляется относительно регистра сегмента ds. Для регистра bp регистром сегмента служит регистр сегмента стека ss. Для изменения сегментных регистров, принятых по умолчанию, можно использовать операцию изменения префикса сегмента. Например, команда

mov es:[bx], dx

пересылает слово из регистра dx в ячейку памяти находящуюся в сегменте, адресуемом текущим содержимым сегментного регистра es (вместо ds) со смещением, находящемся в регистре bx.

Ввод строки с помощью функции OAh прерывания 21h

Для ввода строки с помощью функции 0Ah прерывания 21h область ввода должна быть описана специальным образом:

1 байт 1 байт Буфер для ввода символов

Первый байт содержит число, равное размеру буфера для ввода символов. Во втором байте будет храниться число, равное количеству введенных символов.

Вводимые символы будут сохраняться в буфере, начиная с третьего байта от начала описываемой области.

Итак, описать область для ввода строки из 10 символов можно как

Stroka   DB   11, ?, 11 DUP(?).

Длина строки и размер буфера задаются на единицу больше, так как один символ нужен для хранения числа 0dh – кода клавиши Enter.

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

MaxLength       DB 11
CurrentLehgth DB ?
Buffer                 DB 11 DUP(?)
;знак вопроса означает, что начальное
;значение данной ячейки памяти не определено

Вызов функции 0Ah выглядит так:

mov	AH, 0Ah	;номер функции заносим в регистр AH.
;в DX заносим адрес начала области ввода
mov	DX, OFFSET MaxLength	 
;таким же образом загружается адрес начала области ввода для Stroka
;mov 	DX, OFFSET Stroka
int	21h	;вызов прерывания

Рассмотрим план решения задач, представленных далее, на примере следующей задачи. С клавиатуры вводится строка s1. Необходимо скопировать из нее в строку s2 первый и последний символы и вывести на экран обе строки. Для этого в сегменте данных определим следующие области:

message	DBEnter the string:,10,13,$;приглашение к вводу
maxlength DB   11		;максимально допустимая длина строки
				;последним введенным символом
;будет символ с кодом 13 (0dh шестнадцатеричное – код клавиши Enter)
curlength DB   ?		;текущая длина строки равна количеству
				;введенных символов без учета кода Enter
s1	  DB   11 DUP(?)	;буфер, в который будут помещаться 
				;вводимые символы
s2	  DB   3 DUP(?)		;вторая строка: 2 позиции под буквы и одна
				;позиция под символ $ – признак конца 
				;строки для 9–ой функции
new_line  DB  10,13,$;строка, которая будет использоваться для 
;перевода курсора на новую строку

Далее программу можно составлять по следующему сценарию:

1. Выводим строку message на экран.
2. Вводим строку s1 на экран.
3. Копируем первый символ из s1 в s2 через регистр AL:

mov     AL, s1
mov     s2, AL

4. Помещаем в BX количество введенных символов:

mov      BL, curlength
mov      BH, 0

5. Копируем последний символ из s1 в s2 на вторую позицию через регистр AL:

mov      AL, s1[BX–1]
mov      s2+1,AL

6. Помещаем символ $ в конец строк s1 и s2:

mov s2+2,’$’
mov s1[bx],’$’

7. Выводим строку s1 на экран.
8. Выводим строку new_line.
9. Выводим строку s2 на экран.
10. Выводим строку new_line.
11. Завершаем программу с помощью функции 04ch прерывания 21h.

Задания

  1. Написать программу, соответствующую вашему варианту.
  2. Выполнить программу под управлением отладчика TD. Провести пошаговую трассировку программы, прослеживая на каждом шаге содержимое сегмента данных. Изучить изменение командного указателя IP и сегмента данных от шага к шагу выполнения программы.

Варианты задач

  1. Ввести строку s1 длиной не менее 10 символов. Скопировать в строку s2
    2–ой, 4–ый и 6–ой символы из строки s1. Вывести на экран строки s1 и s2.
  2. Ввести строку s1 длиной не менее 10 символов. Скопировать в строку s2
    10–ый, 5–ый и 2–ой символы из строки s1. Вывести на экран строки s1 и s2.
  3. Ввести строку s1 длиной не менее 10 символов. Скопировать в строку s2 каждый 3-ий символ из строки s1. Вывести на экран строки s1 и s2.
  4. Ввести строку s1 длиной не менее 10 символов. Скопировать в строку s2 все символы, стоящие на нечетных позициях из строки s1. Вывести на экран строки s1 и s2.
  5. Ввести строку s1 длиной не менее 10 символов. Скопировать в строку s2 все символы, стоящие на четных позициях из строки s1. Вывести на экран строки s1 и s2.
  6. Ввести строку s1 длиной не менее 10 символов. Скопировать в строку s2 три последних символа в прямом порядке из строки s1. Вывести на экран строки s1 и s2.
  7. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 три первых символа. Вывести на экран строки s1 и s2.
  8. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 три первых символа в обратном порядке. Вывести на экран строки s1 и s2.
  9. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 три последних символа в обратном порядке. Вывести на экран строки s1 и s2.
  10. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 последний символ три раза. Вывести на экран строки s1 и s2.
  11. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 предпоследний символ три раза и первый. Вывести на экран строки s1 и s2.
  12. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 пятый символ два раза и три раза второй. Вывести на экран строки s1 и s2.
  13. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 первые 3 символа два раза. Вывести на экран строки s1 и s2.
  14. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 второй и четвертый символы три раза. Вывести на экран строки s1 и s2.
  15. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 девятый символ – три раза, второй – два раза. Вывести на экран строки s1 и s2.
  16. Ввести строку s1 длиной не менее 10 символов. Скопировать из строки s1 в строку s2 последний и предпоследний символы два раза. Вывести на экран строки s1 и s2.
рассказать друзьям и получить подарок

Оставить комментарий

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Translate Переводчик

Подписка на новости

SmartResponder.ru
Ваш e-mail: *
Ваше имя: *

Хостинг для Wordpress сайтов