- •Магомедов и. А. Микропроцессорные системы. Аппаратные и программные средства.
- •Глава 1. Микропроцессоры
- •Глава II. Программирование микропроцессоров
- •Глава III. Лабораторный практикум по программированию мп i80х86
- •Глава 1. Микропроцессоры
- •1.1. Назначение микропроцессоров
- •1.2. Универсальные микропроцессоры
- •1.2.2. Микропроцессоры компании amd
- •1.2.3. Микропроцессоры компании Cyrix
- •1.2.4. Микропроцессоры с архитектурой Alpha
- •1.2.5. Микропроцессоры с архитектурой sparc
- •1.2.6. Микропроцессоры Hewlett-Packard ра-8000
- •1.3. Микропроцессоры обработки сигналов
- •1.3.1. Сигнальные микропроцессоры компании
- •1.3.2. Сигнальные микропроцессоры компании Motorola
- •1.3.3. Микропроцессоры семейства dsp 560хх
- •1.4. Медийные микропроцессоры
- •1.5. Транспьютероподобные микропроцессоры
- •1.6. Нейропроцессоры
- •Глава II. Программирование микропроцессоров
- •2.1. Программная модель 32-разрядных процессоров
- •2.1.2. Типы данных
- •2.1.3. Регистры процессора
- •2.2. Форматы команд
- •2.3. Выбор операнда
- •2.4. Режимы адресации
- •Вопросы для самоконтроля к главе 2
- •Глава III. Лабораторный практикум по программированию мп i86
- •Обобщенная структурная схема микропроцессора х86
- •Организация основной памяти и средства аппаратной поддержки управления памятью
- •Выполнение программы
- •Формат операторов ассемблера
- •Определение полей памяти для размещения данных.
- •3.2. Операнды команд ассемблера
- •Команда пересылки данных
- •Команда загрузки исполнительного адреса
- •Команды загрузки указателя.
- •Команда записи в стек
- •Команда обмен данными
- •Команды сложения/ Команды вычитания
- •Команда изменения знака
- •Команда добавления /вычитания единицы
- •Команда сравнения
- •Команды умножения/ деления
- •Команда преобразования байта в слово, а слова - в двойное слово.
- •Команды передачи управления
- •Команды условного перехода
- •Команды организации циклической обработки
- •Команда перехода по обнуленному счетчику
- •Команды организации цикла с условием
- •Команды вызова подпрограмм
- •Команда возврата управления
- •Команды обработки строк
- •Логические команды
- •2. Программирование циклических процессов.
- •3. Моделирование одномерных массивов
- •4. Моделирование матриц
- •5. Преобразования ввода-вывода.
- •3.4. Основные команды отладчика afd
- •Fspec определяет имя файла, наименованного в соответствии с соглашениями dos. Для команды l расширением по умолчанию является “exe”;
- •String задает список значений или ascii строк (строка заключена в кавычки) разделенных пробелами или запятой.
- •Например: 1234 bx, ‘tromb’ ff.
- •Лабораторная работа № 1 Создание выполнимого файла, работа в отладчике, изучение оператора пересылки mov
- •Оператор mov
- •Индивидуальные задания
- •Лабораторная работа № 2 Сегментация памяти, директивы ассемблера
- •Прямая адресация
- •Косвенная адресация
- •Директива assume
- •Индивидуальные задания
- •Лабораторная работа №.3 Директивы equ, label, команды сложения и вычитания Директива equ
- •Директива label
- •Команды сложения и вычитания
- •Индивидуальные задания Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Вариант 11.
- •Вариант 12.
- •Лабораторная работа № 4 Изучение операторов обмена xchg и xlat
- •Индивидуальные задания Вариант 1.
- •Вариант 2.
- •Вариант 3.
- •Вариант 4.
- •Вариант 5.
- •Вариант 6.
- •Вариант 7.
- •Вариант 8.
- •Вариант 9.
- •Вариант 10.
- •Вариант 11.
- •Вариант 12.
- •Система команд процессораi486
- •П1. Команды пересылки данных
- •П2. Арифметические команды
- •П3. Логические команды
- •П4. Команды переходов
- •П5. Команды процессора i486
4. Моделирование матриц
Значения матрицы могут располагаться в памяти по строкам и по столбцам. Для определенности будем считать, что матрица расположена в памяти построчно.
При моделировании обработки матрицы следует различать просмотр по строкам, просмотр по столбцам, просмотр по диагоналям и произвольный доступ.
Просмотр по строкам иногда может выполняться так, как в одномерном массиве (без учета перехода от одной строки к другой).
Пример.
Написать процедуру определения максимального элемента матрицы A(3,5).
mахмatr proc
mov bx, 0 ; смещение 0
mov cx, 14 ; счетчик цикла
mov ax, A ; заносим первое число
cycl: cmp ax, A[bx+2] ; сравниваем числа
jge next ; если больше, то перейти к следующему
mov ax, A[bx+2] ; если меньше, то запомнить
next: add bx, 2 ; переходим к следующему числу
loop cycl
ret ; результат в ax
mахмatr endp
Просмотр по строкам при необходимости фиксировать завершение строки и просмотр по стобцам выполняются в двойном цикле: по строкам - во внешнем цикле, по столбцам - во внутреннем или наоборот. В этом случае обычно отдельно формируются смещения строки и столбца.
Пример.
Определить сумму максимальных элементов столбцов матрицы A(3,5).
mахмatr proc
mov ax, 0 ; обнуляем сумму
mov bx, 0 ; смещение элемента столбца в строке
mov cx, 5 ; количество столбцов
cycl1: push cx ; сохраняем счетчик
mov cx, 2 ; счетчик элементов в столбце
mov dx, A[bx] ; заносим первый элемент столбца
mov si, 10 ; смещение второго элемента столбца
cycl2: cmp dx, A[bx]+ [si] ; сравниваем
jge next ; если больше или равно - к следующему
mov dx, A[bx]+[si] ; если меньше, то сохранили
next: add si, 10 ; переходим к следующему элементу
loop cycl2 ; цикл по элементам столбца
add ax, dx ; просуммировали макс. элемент
pop cx ; восстановили счетчик
add bx, 2 ; перешли к следующему столбцу
loop cycl1 ; цикл по столбцам
ret ; результат в ax
mахмatr endp
5. Преобразования ввода-вывода.
При программировании операций ввода-вывода на ассемблере приходится вручную осуществлять преобразования чисел из символьного представления во внутренний формат (двоичный с фиксированной точкой, отрицательные числа записаны в дополнительном коде) и обратно.
Для облегчения преобразования во внутренний формат целесообразно оговорить возможные варианты ввода чисел в символьном виде. При этом также используется то, что при добавлении цифры к числу справа число меняется следующим образом: <число>:=<число>*10+<цифра>.
Обратное преобразование из внутреннего формата в символьный для вывода результатов обычно использует стандартное правило перевода числа из двоичной системы счисления в десятичную: деление на 10 с выделением остатков. В этом случае десятичные цифры получаются в обратном порядке.
Если среди вводимых или выводимых чисел могут быть отрицательные, то необходимо предусмотреть специальную проверку и преобразовывать отрицательные числа в дополнительный код при вводе и в прямой при выводе.
Пример.
Написать процедуры ввода массива из n чисел размером слово и вывода того же массива. Числа должны вводиться каждое со своей строки, положительные числа должны вводиться без знака c первой позиции, отрицательные - со знаком в первой позиции. Вывод всех чисел должен осуществляться в одну строку через пробелы. Перед отрицательными числами необходимо выводить знак "-".
Составить тестирующую программу.
title inout
code segment
assume cs:code, ds:code
N equ 5 ; определяем константу для транслятора
A dw N dup (?) ; резервируем место под массив
main proc far ; основная процедура
push ds ; обеспечиваем возврат управления в MS DOS
mov ax, 0
push ax
mov ax, code ; загружаем сегментный адрес
mov ds, ax ; сегмента данных в DS
call input ; вызываем процедуру ввода
call output ; вызываем процедуру вывода
ret ; возврат управления DOS
main endp ; конец основной процедуры
input proc near ; процедура ввода
mov cx, N ; загругка размерности массива
mov di, 0 ; загрузка смещения массива
cycl1_in: push cx ; сохраняем счетчик внешнего цикла
lea dx, mes_in ; загружаем адрес запроса на ввод
mov ah, 9 ; загружаем номер функции DOS
int 21h ; вызываем функцию вывода строки
lea dx, BUf_in ; загружаем адрес строки ввода
mov ah, 0ah ; загружаем номер функции DOS
int 21h ; вызываем функцию ввода строки
mov byte ptr NEG_IN, 0 ; признак - "число положительно"
cld ; флаг направления - "возрастание адресов"
mov cl, BUF_IN+1 ; загружаем длину введенной строки
mov ch, 0 ; счетчик - в CX
lea si, BUF_IN+2 ; загружаем адрес введенной строки
cmp byte ptr [si], '-' ; число отрицательно ?
jne short unsigned ; если нет, то переход
mov byte ptr NEG_IN, 1 ; признак - "число отрицательно"
inc si ; пропускаем знак
dec cx ; уменьшаем счетчик
unsigned: mov bx, 0 ; исходное значение числа
cycl2_in: mov ax, 10 ; заносим константу 10
mul bx ; умношаем текущее значение числа на 10
mov bx, ax ; текущее значение числа в BX
lodsb ; загрузили очередную цифру
sub al, 30h ; преобразовали из символа в двоичное число
cbw ; преобразовали в слово
add bx, ax ; добавили к текущему значению числа
loop cycl2_in ; выполняем для всех введенных цифр
cmp NEG_IN, 0 ; число положительно ?
je short done ; если да, то переход
neg bx ; преобразуем в отричательное число
done: mov A[di], bx ; записываем результат в массив
add di, 2 ; корректируем смещение
pop cx ; восстанавливаем счетчик внешнего цикла
loop cycl1_in ; выполняем для всех чисел
ret ; возвращаем управление основной процедуре
BUF_IN db 10,10 dup (0) ; буфер ввода (до 10 символов)
NEG_IN db 0 ; признак "положительно/отрицательно"
mes_in db 13,10,'Введите число: $' ; запрос на ввод
input endp
output proc near ; процедура вывода
lea dx, mes_out ; загружаем адрес заголовка вывода
mov ah, 9 ; загружаем номер функции DOS
int 21h ; вызываем функцию вывода строки
mov cx, N ; загружаем количество чисел
mov si, 0 ; устанавливаем смещение в массиве
mov di, 7 ; устанавливаем смещение для строки вывода
cycl1_out: mov byte ptr NEGOUT, 0 ; признак - "число положительно"
mov bx, 10 ; загрузили константу 10
mov ax, A[si] ; взяли очередное число из массива
cmp ax, 0 ; сравнили с нулем
jge short again ; если положительно, то переход
mov byte ptr NEG_OUT, 1 ; признак "число отрицательно"
neg ax ; преобразовали в положительное
again: cwd ; преобразовали в двойное слово
div bx ; разделили на 10
add dl, 30h ; преобразовали остаток в символ
mov BUF_OUT[di], dl ; записали в поле вывода
dec di ; уменьшили смещение в поле вывода на 1
cmp ax, 0 ; сравнили результат деления с нулем
jne again ; если не равно, то получаем следующую цифру
cmp byte ptr NEG_OUT, 1 ; число отрицательно
jne short positive ; если нет, то переход
mov BUF_OUT[di], '-' ; если да, то вставили знак "-"
positive: mov ax, N+2 ; считаем смещение следующего числа
sub ax, cx ; в поле вывода
mov bx, 7 ;
mul bx ;
mov di, ax ; записали смещение в DI
add si, 2 ; перешли к следующему числу массива
loop cycl1_out ; выполняем для всех чисел массива
lea dx, BUF_OUT ; загружаем адрес строки вывода
mov ah, 9 ; загружаем номер функции DOS
int 21h ; вызываем функцию вывода строки
ret ; возврат в основную процедуру
NEG_OUT db 0 ; признак "положительно/отрицательно"
BUF_OUT db 13,10, N*7 dup (' '),'$' ; поле вывода
mes_out db 13,10,'Результат: $' ; заголовок вывода
output endp
code ends
end main
