Справочник от Автор24
Поделись лекцией за скидку на Автор24

Программная модель МП

  • 👀 258 просмотров
  • 📌 186 загрузок
Выбери формат для чтения
Загружаем конспект в формате pdf
Это займет всего пару минут! А пока ты можешь прочитать работу в формате Word 👇
Конспект лекции по дисциплине «Программная модель МП» pdf
Программная модель МП Microprocessor Bus Control unit Datapath ALU Reg. Memory Output units Input units What are microprocessors?  A microprocessor is a processor (or Central Processing Unit, CPU) fabricated on a single integrated circuit. Address bus MAR PC IR Control unit Control bus X Data bus Y ALU ACC A simple microprocessor architecture Other Commercial Microprocessors  PowerPC (IBM, Motorola)  Athlon, Dulon, Hammer (AMD)  Crusoe (Transmeta)  SPARC, UltraSPARC (Sun Microsystems)  TI’s TMS DSP chips (Texas Instruments)  StarCore (Motorola, Agere)  ARM cores (Advanced RISC Machines)  MIPS cores (MIPS Technologies)   Applications of Microprocessor-Based Systems  Computers  System performance is normally the most important design concern ... Keyboard Monitor Disk Other peripherals Bus Microprocessor Memory Timing & control Block diagram of a computer ... Interrupt control Applications of Microprocessor-Based Systems  Microcontrollers  A microcontroller is a simple computer implemented in a single VLSI chip.  In general, microcontrollers are cheap and have low performance  Microcontrollers are widely used in industrial control, automobile and home applications OSC. RAM ROM CPU I/O port Timer USART Interrupt A/D, D/A Block diagram of a microcontroller Applications of Microprocessor-Based Systems  ASICs http://www.ti.com  Microprocessors are embedded into ASIC chips to implement complex functions  In general, it requires that the microprocessors have low power consumption and take small silicon area A TI baseband chip for cellular phone applications Class Objectives  Hardware architecture of microprocessor-based systems  Microprocessor architecture  Memory organization  I/O units of microprocessor-based systems  How to put them together  Programming of microprocessor-based systems  Intel 80x86 instruction set  Microprocessor Interrupt services  Assembly language programming Topics 1. Introduction of microprocessor-based systems 2. Intel 8088 microprocessor architecture 3. Memory organization in microprocessor-based systems 4. Intel 80x86 instruction set 5. Assembly language programming 6. I/O systems 7. Microprocessor interrupt and interrupt services 9. Disk systems and file 10. Topics in advanced computer architecture Принципы фон Неймана • • • • • Использование двоичной системы счисления в вычислительных машинах. Программное управление ЭВМ. Работа ЭВМ контролируется программой, состоящей из набора команд. Команды выполняются последовательно друг за другом. Созданием машины с хранимой в памяти программой было положено начало тому, что мы сегодня называем программированием. Память компьютера используется не только для хранения данных, но и программ. Ячейки памяти ЭВМ имеют адреса, которые последовательно пронумерованы. В любой момент можно обратиться к любой ячейке памяти по ее адресу. Этот принцип открыл возможность использовать переменные в программировании. Возможность условного перехода в процессе выполнения программы. Не смотря на то, что команды выполняются последовательно, в программах можно реализовать возможность перехода к любому участку кода. Системы счисления Десятичная  Двоичная  Шестнадцатеричная  Десятичная система счисления Двоичная система счисления Шестнадцатиричная система счисления INTEL 8086 General Purpose Registers Представление положительных и отрицательных чисел Режимы адресации (начало) Режимом адресации - способ определения местонахождения операнда. Различают семь основных режимов адресации данных, которые можно разделить на две группы. К первой относят режимы, в которых место, в котором находится операнд, указывается непосредственно в команде. Это – непосредственный, регистровый и прямой режимы адресации. Непосредственный режим адресации Операнд располагается в самой команде в виде двоичного числа. Операнд обычно представляет собой константу, которую надо куда-то переслать, к чему-то прибавить, с чем-то сравнить и т.д. Прямой режим адресации Прямая (или абсолютная) адресация предполагает, что в команде после кода операции располагается внутрисегментный адрес ячейки памяти. По этому адресу хранится операнд. Регистровый режим адресации В команде указан один из регистров процессора, в котором хранится операнд. CPU Сегментирование памяти Для хранения кодов адресов памяти используются не отдельные регистры, а пары регистров: • сегментный регистр определяет адрес начала сегмента (то есть положение сегмента в памяти); • регистр смещения определяет положение рабочего адреса внутри сегмента. Формирование физического адреса памяти из адреса сегмента и смещения Физический 20-разрядный адрес памяти, выставляемый на внешнюю шину адреса, образуется путем сложения смещения и адреса сегмента со сдвигом на 4 бита. Положение этого адреса в памяти показано на рисунке. Например, сегмент в шестнадцатеричном виде равен 1200, а смещение — 3АВЕ. Сегмент (1200) 0 0 0 1 0 0 1 0 0 0 0 0 0 0 0 0 Смещение (3АВЕ) 0011110011011110 Адрес (15АВЕ) 00010101110011011110 Сегментация памяти Память 00000 00010 + FFFF 1000F 00010 00020 1 сегмент 2 сегмент 3 сегмент 1000F 10010 Чаще всего используемой командой процессора, является команда MOV Operand_1, Operand_2 Данная команда копирует содержимое правого операнда в левый операнд. Эта команда, равно как и практически все остальные команды, оперирующие парой операндов, удовлетворяет двум важным условиям: Рассмотрим команду mov AH, 2h B Команда MOV MOV MOV MOV MOV MOV MOV MOV 4 2 Операнды AL, imm8 CL, imm8 DL, imm8 BL, imm8 AH, imm8 CH, imm8 DH, imm8 BH, imm8 Код B0 B1 B2 B3 B4 B5 B6 B7 Рассмотрим команду mov DL, 2Ah B 2 2 A Команда MOV MOV MOV MOV MOV MOV MOV MOV Операнды AL, imm8 CL, imm8 DL, imm8 BL, imm8 AH, imm8 CH, imm8 DH, imm8 BH, imm8 Код B0 B1 B2 B3 B4 B5 B6 B7 Формат кодирования команд ассемблера [метка] [префикс] команда [операнд(ы)] ; [комментарий] Метка (если имеется), команда и операнд (если имеется) pазделяются по крайней мере одним пробелом или символом табуляции. Максимальная длина строки - 132 символа Метка count Команда Операнд db mov 1 ax, ;Имя, команда, один операнд ;Команда, два операнда Метки Метка в языке ассемблера может содержать следующие символы: Буквы: Цифры: Спецсимволы: знак вопроса точка знак подчеркивание доллар от a до z и от a до z от 0 до 9 (?) (.) (только первый символ) (@) (_) ($) Метки - ограничения      Первым символом в метке должна быть буква или спецсимвол. Ассемблер не делает различия между заглавными и строчными буквами. Максимальная длина метки - 31 символ. Примеры меток: count, page25, $e10, .cursor Рекомендуется использовать описательные и смысловые метки. Имена регистров, например, AX, DI или AL и т.д. являются зарезервированными и используются только для указания соответствующих регистров. Функции DOS Код функции в рег-р  AH  Заполнение других РОН в соответствии с описанием функции  Вызов DOS  int 21h  Инструкция int - interrupt – программное прерывание  Вывод на экран символа 2h  AH – номер функции 41h  DL – код символа INT 21H – вызов функции DOS mov mov INT INT AH, DL, 21H 20H 02h 2Ah ; загружаем в AH число 02h ; загружаем в DL число 2Ah ; печать * на экране ; exit Первая программа code_seg segment assume cs:code_seg, ds:code_seg org 100h start: mov AH, 2h mov DL, 2Ah ; в DL ASCII код int 21h int 20h ; выход из программы code_seg ends end start Листинг трансляции Файл PRIM1.LST Turbo Assembler Version 3.1 PRIM1.ASM 1 0000 2 3 4 0100 5 0100 B4 02 6 0102 B2 2A 7 0104 CD 21 8 0106 CD 20 9 0108 10 21/02/05 01:42:50 Page 1 code_seg segment assume CS:code_seg, DS:code_seg org 100h start: mov AH, 2h mov DL, 2Ah int 21h int 20h code_seg ends end start Вывод на экран строки символов Функция 02h – Выводит 1 символ  Функция 09Н – печатает целую строку, пока не встретит символ ‘$’  mov lea Int 21H AH, DX, 09 mes ; 09h≡ 9H ≡ 9 ≡ 11O ≡ 1001B ; адрес сообщения Пример 2 code_seg segment assume cs:code_seg,ds:code_seg,ss:code_seg org 100h start: jmp begin mes DB 13,10,’Привет',13,10,'$' begin: mov AH, 9h lea DX, mes int 21h int 20h code_seg ends end start Листинг трансляции (пример 2) Turbo Assembler Version 3.1 PRIM2.ASM 1 0000 2 cs:code_seg,ds:code_seg,ss:code_seg 3 4 0100 5 0100 EB 0C 90 6 0103 0D 0A AF E0 A8 A2 A5+ 7 E2 0D 0A 24 8 010E 9 010E B4 09 10 0110 BA 0103r 11 0113 CD 21 12 0115 CD 20 13 0117 14 13 10 21/02/05 01:17:20 Page 1 code_seg segment assume org 100h start: jmp begin mes DB 13,10,'привет',13,10,'$' begin: mov AH, 9h lea DX, mes int 21h int 20h code_seg ends end start Вывод на экран шестнадцатеричной цифры Сhar ASCII Code (HEX) / 2F 30 1 31 2 32 3 33 4 34 5 35 6 36 7 37 8 38 9 39 : 3A ; 3B 3C = 3D 3E ? 3F @ 40 mov mov цифры 0 int 21h AH, 02h DL, 30h ; вывод + 30h mov AH, 02h mov DL, 39h ; вывод цифры 9 int 21h 7 Вместо хранения таблицы ASCII в программе, код цифры можно сформировать сложением цифры и константы 30h Продолжение ASCII таблицы @ 40 A 41 B 42 C 43 D 44 E 45 F 46 G 47 mov AH, 02h mov DL, 41h ; вывод цифры (буквы) A int 21h +037H РОН = РОН+ 030h if РОН  03Ah then РОН=РОН+07h Print РОН Пример: 0A+30h=3Аh 3Ah+07h=41h На ассемблере: mov AH, 02h mov DL, BL add DL, 030h cmp DL, 3Ah jl print_letter add DL, 07h print_letter: int 21h Вывод на экран содержимого младшей тетрады регистра BL code_seg segment assume CS:code_seg,DS:code_seg,SS:code_seg org 100h start: mov AH, 9h ; функция DOS для вывода стр.символов ( $ ; ограничитель стр.) lea DX, mes ;≡ mov DX, offset mes int 21h ; print string ; mov BL, 0Fh ; загружаем в BL известное число, чтобы ; проверить правильность вывода mov AH, 02h mov DL, BL add DL, 30h cmp DL, 3Ah jl print add DL, 07h print: int 21H int 20h mes DB 13,10,'я печатаю HEX содержимое мл. тетрады регистра BL',13,10,'$‘ code_seg ends end start Процедура Это список инструкций, который можно вызвать из различных мест программы. Аналог функции в С и подпрограммы. Процедуру можно вызвать с помощью CALL имя процедуры выход из процедуры ret. Адрес возврата запоминается в стеке. Call … … prim prim prim proc [near], [far] инструкция ... инструкция ... ret endp тело процедуры Вывод на экран содержимого регистра BL mov rcr call mov call int ; print_hex mov and add cmp jl add print: ret print_hex DL, BL DL, 4 print_hex DL, BL print_hex 20h proc near AH, 02h DL, 0Fh DL, 030h DL, 03Ah print DL, 07h int 21h endp ; сдвиг вправо на 4 бита Команды циклического сдвига CF 1 1 1 1 1 1 1 1 1 1 1 1 rcr DL, 4 результат rcl DL, результат 4 Поразрядное логическое AND 1 1 1 1 1 1 1 1 1 and DL, результат 0Fh Cформировать байт из 2-х шестнадцатиричных цифр code_seg segment assume cs:code_seg,ds:code_seg,ss:code_seg org 100h start: jmp write_string mes: DB 13,10,'Я формирую байт из 2х вводимых HEX цифр',13,10,'$' write_string proc near mov AH, 9h ; функция DOS для вывода строки символов ; $ - ограничитель строки lea DX, mes int 21h ; print string write_string endp ; main proc near ; Ввод шестнадцатеричных цифр call inp_hex mov DL,AL rol DL,4 call inp_hex add DL,AL int 20h main endp inp_hex proc push cycle: mov int cmp jb cmp ja cmp ja mov mov int sub pop ret near DX AH, 21h AL, beep AL, beep AL, cont AH, DL, 21h AL, DX 08h ; function - input char without echo 030h ; if < beep (unsigned) 046h ; if > beep (unsigned) 039h 02h AL ; print char 030h ; code ASCII-030h--> hex digit beep: mov mov int jmp AH, DL, 21h short 02h 07h cycle cont: cmp AL, jb beep mov AH, mov DL, int 21h sub AL, pop DX ret inp_hex endp code_seg ends end start 041h 02h AL 037h ; code of beep Домашнее задание Вывод содержимого регистра BX  Ввод 4-х шестнадцатиричных цифр и формирование из них содержимого регистра BX  Вывод на экран двоичного числа code_seg segment assume cs:code_seg,ds:code_seg,ss:code_seg org 100h start: jmp begin mes: DB 13,10,'я печатаю двоичное содержимое регистра BX',13,10,'$' begin: mov AH, 9h ; функция DOS для вывода строки символов ; $ - ограничитель строки lea DX, mes int 21h ; print string ; mov BX, 0A3C5h mov CX, 16 mov AH, 02 ; функция- печать символа из DL cycle: rcl BX, 1 ; цикл. сдвиг BX на 1 разряд влево xor DL, DL ; сложение с учетом значения флага переноса CF adc DL, 30h int 21H приемник=приемник+источник+CF loop cycle int 20h code_seg ends end start Если шестнадцатеричное число начинается с буквы, то в программе такое число должно записываться с ведущим 0 (для того, чтобы отличить от меток или от обозначения регистров), Например, число А – 0Ah, а не Ah – чтобы не спутать с регистром AH. Работа с файлами В DOS доступны следующие функции работы с файлами:  39h – создать каталог файлов (аналогично функции MKDIR DOS)  3Аh – удалить каталог  3Вh – сменить текущий каталог  3Сh – создать файл (CREATE)  3Dh – открыть файл (OPEN)  3Eh – закрытие файла (CLOSE)  3Fh – читать данные из файла или устройства (READ)  40h – записать данные в файл или на устройство (WRITE)  41h – удалить файл (DELETE)  42h – переместить указатель текущей позиции в файле  43h – получить/установить аттрибуты файла  56h – переименовать файл  57h – получить/установить дату и время последнего изменения файла  5Ah – создать временный файл  5Bh – создать новый файл (В отличие от 3Сh, если файл уже существует, то 5Bh сообщает об ошибке).  5Сh – блокировать/разблокировать доступ к файлу. Работа с каталогом  39h – создать каталог файлов (аналогично функции MKDIR DOS) перед использованием DS:DX – адрес ASCIIZ – строки –имя пути для нового каталога. Ошибки в АХ: 3 - путь не найден 5 – ошибка в доступе  3Аh – удалить каталог DS:DX – адрес ASCIIZ – строки –имя пути для нового каталога. Ошибки в АХ те же  3Вh – сменить текущий каталог DS:DX – адрес ASCIIZ – строки –имя пути для нового каталога Ошибки в АХ: 3 - путь не найден АSCIIZ-строка  Функции DOS, работающие с файлами, требуют задания имени и пути к файлу в виде ASCIIZ строки. ASCIIZ строка состоит из обычных ASCII символов, за которыми следует нулевой байт. Типичная строка выглядит наподобие:  C:\DIRECTORY1\DIRECTORY2\FILENAME.EXT  В качестве разделителя может быть как прямая, так и обратная косая черта. (имя дисковода может быть опущено) Функция - создать файл   3Сh – создать файл (CREATE) открывает существующий или создает новый файл. DS:DX – адрес ASCIIZ строки. СХ – атрибут файла АХ – возвращается логический номер файла. Логический номер файла или дескриптор – это 16-битовое число, используемое DOS как указатель на систему таблиц. Логический номер освобождается после закрытия файла и может быть использован повторно. Особенности функции - CREATE   После выполнения всех необходимых действий по созданию файла, функция 3Сh возвращает в регистре АХ дескриптор созданного файла, которым мы можем в дальнейшем пользоваться для записи в файл или чтения из него. Если файл с заданным именем уже существовал, функция 3Сh фактичеки уничтожит имеющийся файл и создаст новый с тем же именем. Атрибут файла В СХ, а точнее, в СL задается – атрибут файла  0 – отсутствие атрибутов  1 – только чтение  2 – скрытый файл  4 – системный  8 – метка тома  16 = 10h – подкаталог  32 = 20h – архив – этот разряд сброшен для всех файлов, которые изменялись после последнего копирования Существует пять стандартных логических номеров 0 - 4, которые автоматически предоставляются любой программе Логически й номер Использование Устройство по умолчанию Стандартный ввод (клавиатура) CON: 1 Стандартный вывод (экран) CON: 2 Стандартное устройство вывода при ошибке CON: 3 Стандартное вспомогательное устройство AUX: 4 Стандартное устройство печати PRN: Остальные номера с большими логическими номерами DOS предоставляет по требованию Проверка ошибок  Так как АХ используется для возврата как логического номера, так и кода ошибки, то в качестве признака ошибки используеся флаг CF (флаг переноса)  Возможны коды возврата: 3 – путь не найден 4 – нет свободного логического номера 5 – отказ в доступе – либо в каталоге нет места для новой записи, либо уже существующий файл защищен от записи и не может быть открыт для вывода данных. Файловая функция mov AH, 3Ch ; AH 3Ch, 3D, …. …. …. int 21h нет Произошла ошибка, в AX – код ошибки CF=0 ? да Ошибок нет – в AX - дескриптор Анализ системных ошибок MOV AH, Function ; Номер функции ; Заполнение регистров параметрами, ; необходимыми для ; выполнения данной функции INT 21h JC Error ; флаг СF установлен ; Нет, нормальное продолжение программы ………… Error: … ; Да, анализ ошибок в АХ CMP AX, 1 JE Error1 CMP AX, 2 JE Error2 ….. Функция 3Dh - открыть файл (OPEN) DS:DX – адрес строки, содержащей путь и имя файла AL - код режима открытия Рассмотрим только разряды 02. 2 1 1 1 Только чтение Только запись Чтение/запись Бит 7 – бит наследования Биты 4-6 – режимы совместного использования. Коды возврата в АХ: 2 – файл не найден 3 – путь не найден 4 – нет свободного логического номера файла 5 – отказ в доступе 12 – недопустимый код доступа 3Eh – закрыть файл (CLOSE) Логический номер в  ВХ Номер функции 3Eh  AH int 21h Код ошибки: 6 – ошибочный логический номер 3Fh – читать данные из файла (READ) Логический номер Число байт Адрес буфера  ВХ  СХ  DS:DX В АХ возвращается число действительно считанных байтов Если в АХ 0, то программа пыталась считать данные за концом файла Код ошибки: 5 – отказ в доступе 6 – ошибочный логический номер Процесс чтения из файла память устройство Указатель текущей позиции в файле файл Область программы DS:DX Буфер ввода Размер число байт в CX Дескриптор в BX 40h – записать данные в файл (WRITE)         Логический номер  ВХ. Число байт  СХ Адрес выводимых данных  DS:DX В АХ возвращается число действительно выведенных байтов. Проверка состоит их 2х шагов СF=1? AX = CX? Если АХ<СХ – на диске не хватило места. 41h – удалить файл (DELETE) DS:DX – адрес строки, определяющей имя файла.  Заполнители ? и * в имени файла использовать нельзя.  42h – переместить указатель текущей позиции в файле          Логический номер – ВХ. Новое положение указателя задается путем загрузки в регистр AL исходного положения указателя, а в пару регистров СХ:DX – число байтов, на которое необходимо переместить указатель. Загружаемое в пару регистров СХ:DX смещение в байтах – это 32-битовое число без знака. В СХ – старшая часть, в DX – младшая. Если смещение меньше 65535, то СХ = 0. Исходное положение в АL задается с помощью так называемого кода метода: АL = 0 – смещение берется от начала файла и указатель изменяется на СХ:DX от этой точки АL = 1 – смещение берется от текущей позиции АL = 2 – смещение берется от конца файла. В последнем случае в паре регистров СХ:DX обычно ноль, чтобы определить текущий размер файла. Если задать смещение 0 и запросить метод 0 – то возврат в начало файла. Коды ошибок: 1 – ошибочный номер функции 6 – ошибочный логический номер Пример 1 ; создание файла MOV AH, 3Ch ; Функция CREATE MOV CX, 0 ; Без атрибутов MOV DX, OFFSET Filename ; Адрес имени Файла INT 21h ; Вызов DOS Mov Handler, AX ; сохранить дескриптор ; запись строки в файл MOV AH, 40h ; Функция записи MOV BX, Handler ; Дескриптор MOV CX, BufLen ; Число записываемых байтов MOV DX, OFFSET Buf ; Адрес буфера INT 21h ; закрытие файла MOV AH, 3Eh ; MOV BX, Handler INT 21h ; завершение программы MOV AX, 4C00h ; Функция завершения INT 21h ; данные Buf DB ‘0123456789’ ; Данные, записываемые в файл BufLen EQU $ - Buf ; Длина данных. $ - текущее значение счетчика Handler DW ? ; Ячейка для дескриптора Filename DB ‘D:\test\myfile.txt’,0 ; ASCIIZ строка спецификации файла Пример 2 ; Открыть файл MOV AH, 3Dh ; функция OPEN MOV AL, 2 ; Доступ для чтения/записи MOV DX, OFFSET Filename ; Адрес имени файла INT 21h MOV Handler, AX ; Сохранение дескриптора ; Пытаемся прочитать 80 байт MOV AH, 3Fh ; Функция READ MOV BX, Handler ; Дескриптор MOV CX, 80 ; Сколько читать MOV DX, OFFSET BufIn ; Сюда читать INT 21h MOV CX, AX ; сколько реально прочитано ; Вывод прочитанного на экран MOV AH, 40h ; функция WRITE MOV BX, 1 ; Дескриптор стандартного вывода MOV DX, OFFSET BufIn ; отсюда выводить (СХ байт) Int 21h ; Данные BufIn DB 80 dup (‘ ‘) ; буфер ввода Handler DW ? Filename DB ‘D:\test\myf.txt’,0 ;спецификация файла Функции для работы с файлами 43h – получить, установить аттрибуты файла 56h – переименовать файл 57h – получить/установить дату и время последнего изменения файла в DOS 3.00 5Ah – создать временный файл CX - атрибут DS:DX – имя пути, должно заканчиваться ‘\’ Строка должна иметь длину на 12 байт больше длины имени пути, чтобы DOS могла бы дополнить уникальным именем файла. 5Bh – создать новый файл. В отличие от 3Сh, если файл уже существует, то 5Bh сообщает об ошибке. 5Сh – блокировать/разблокировать доступ к файлу. Программный загрузчик  Ц е л ь: Понять как DOS загружает программу в память и управляет ее исполнением DOS состоит из четырех основных программ 1 Блок начальной загрузки находится на первом секторе нулевой дорожки дискеты DOS, а также на любом диске, форматированном командой FORMAT/S. 2 Программа IBMBIO.COM обеспечивает интерфейс низкого уровня с программами BIOS в ROM. При инициализации программа IBMBIO.COM определяет состояние всех устройств и оборудования, а затем загружает программу COMMAND.COM 3 Программа IBMDOS.COM обеспечивает интерфейс высокого уровня с программами. Эта программа управляет оглавлениями и файлами на диске, блокированием и деблокированием дисковых записей, функциями int 21h, а также содержит ряд других сервисных функций. 4 Программа COMMAND.COM выполняет различные команды DOS, такие как DIR или CHKDSK, а также выполняет com, exe и batпрограммы. Она состоит из трех частей: небольшая резидентная часть, часть инициализации и транзитная часть. Программа COMMAND.COM отвечает за загрузку выполняемых программ с диска в память. Распределение адресного пространства в DOS Физический адрес Содержимое Объем (Кб) 00000h таблица векторов прерываний 640 00400h Область связи с ROM (ПЗУ) 00500h Область связи с DOS 00600h IBMBIO.COM xxxx0h IBMDOS.COM Буфер каталога, Дисковый буфер,Таблица параметров дисковода или таблица распределения файлов (FAT, по одной для каждого дисковода) xxxx0h Резидентная часть COMMAND.COM xxxx0h Внешние команды или утилиты (com или exe-файлы) xxxx0h Пользовательский стек для com-файлов (256 байт) xxxx0h Транзитная часть COMMAND.COM, записывается в самые старшие адреса памяти. A0000h Графический видеобуфер 64 B0000h Свободные адреса 32 B8000h Текстовый видеобуфер 32 C0000h ПЗУ-расширения BIOS 64 D0000h Свободные адреса 64 E0000h ПЗУ BIOS 128 Командный процессор COMMAND.COM Система загружает три части программы COMMAND.COM в память во время сеанса работы постоянно или временно. Ниже описано назначение каждой из трех частей COMMAND.COM: 1. Резидентная часть непосредственно следует за программой ibmdos.com. Резидентная часть обрабатывает все ошибки дисковых операций ввода-вывода и управляет следующими прерываниями: int 22h Адрес программы обработки завершения задачи. int 23h Адрес программы реакции на ctrl/break. int 24h Адрес программы реакции на ошибки дисковых операций чтения/записи или сбойный участок памяти в таблице распределения файлов (FAT). int 27h Завершение работы, после которого программа остается резидентной. Часть инициализации COMMAND.COM 2. Часть инициализации непосредственно следует за резидентной частью и содержит средства поддержки autoexec-файлов. В начале работы системы данная часть первой получает управление. Она определяет сегментный адрес, куда система должна загружать программы для выполнения. Ни одна из этих программ инициализации не потребуется больше во время сеанса работы. Поэтому первая же команда вводимая с клавиатуры и вызывающая загрузку некоторой программы с диска перекрывают часть инициализации в памяти. 3. Транзитная часть COMMAND.COM Транзитная часть загружается в самые старшие адреса памяти. Выводит на экран приглашение C>, вводит и выполняет запросы. Содержит настраивающий загрузчик и предназначена для загрузки COM- или EXE-файлов с диска в память для выполнения. Если поступил запрос на выполнение какой-либо программы, то транзитная часть строит префикс программного сегмента (PSP) непосредственно вслед за резидентной частью COMMAND.COM. Затем она загружает запрошенную программу с диска в память по смещению 100h от начала программного сегмента, устанавливает адреса выхода и передает управление в загруженную программу. Ниже приведена данная последовательность: IBMBIO.COM IBMDOS.COM COMMAND.COM (резидент) Префикс программного сегмента Выполняемая программа ... COMMAND.COM (транзитная часть, может быть перекрыта). Выполнение команды RET или INT 20H в конце программы приводит к возврату в резидентную часть COMMAND.COM. Если транзитная часть была перекрыта, то резидентная часть перезагружает транзитную часть с диска в память Образ памяти программы типа .COM После загрузки программы все четыре сегментных регистра указывают на начало единственного сегмента. Указатель стека автоматически инициализируется числом FFFEh. Таким образом программе выделяется 64 Кб адресного пространства, всю нижнюю часть которого занимает стек. CS, DS, ES, SS PSP IP = 0100h Программа и данные стек SP = FFFEh ПРЕФИКС СЕГМЕНТА ПРОГРАММЫ (PSP) (program segment prefix)   PSP – это область размером 100h (25610), которая содержит информацию, необходимую DOS для обеспечения работы программы. Для СОМ-программы сегментные регистры (CS, DS и ES) указывают на начало PSP, а программа размещается сразу вслед за PSP, то есть со смещением 100h от начала PSP. Структура префикса программного сегмента Поле Смещение от начала PSP Размер поля (десятичн) Значение 1 00h 2 байт Команда INT 20h 2 02h 2 байт Размер памяти в параграфах 3 04h 1 байт Резерв, обычно 0 4 05h 5 байт Вызов диспетчера функций DOS 5 0Ah 4 байт Вектор завершения работы (Адрес завершения CS:IP) 6 0Eh 4 байт Вектор прерывания работы (Адрес выхода Ctrl-Break) 7 12h 4 байт Вектор ошибки (Адрес выхода по ошибке) 8 16h 22 байт Используется DOS 9 2Ch 2 байт Указатель строки связи с окружающей средой 10 2Eh 34 байт Рабочая область DOS 11 50h 3 байт Коменды INT 21h, RETF 12 53h 2 байт Зарезервировано 13 55h 7 байт Расширение FCB #1 14 5Ch 9б айт FCB #1 15 65h 7 байт Расширение FCB #2 16 6Ch 20 байт FCB #2 17 80h 1 байт Длина параметров 18 81h 127 байт Параметры 19 80h 128 байт Область передачи информации Поле 1     Прерывание INT 20h используется для завершения программы и передачи управления DOS. Прерывание INT 20h эквивалентно AH=0 (функции 0) INT 21h. INT 20h не закрывает все открытые этой программой файлы. Более совершенная функция выхода из программы 4Сh - завершает работу программы и передает тому, кто ее вызвал, код возврата. Если программа была вызвана как подпрограмма, то вызвавшая ее программа может получить код возврата с помощью функции 41h. Если программа вызывалась командой DOS, то код возврата может быть проверен в командном файле с помощью команды ERRORLEVEL. Код возврата возвращается в AL. При выполнении этой функции DOS автоматически закрывает все файлы, открытые с помощью 3Dh и, возможно, 3Сh. Итак, команда INT 20h находится в начале PSP . Таким образом, можно выйти из программы, просто передав управление на эту ячейку (при условии, что CS указывает на PSP). Размещение в начале PSP команды INT 20h может быть объяснено тем, что если LINK обнаруживает в программе неудовлетворенную внешнюю ссылку, то он присваивает ее адресу смещения 0. при передаче управления на эту ссылку выполнится команда, находящаяся в начале PSP, то есть INT 20h, - что вызовет завершение программы. Поле 2   сколько памяти доступно – содержит номер последнего блока памяти, доступной DOS. Умножив это число на 16, получим общий объем памяти в байтах. То же самое значение, что и в поле 2, возвращает команда CHKDSK DOS. Если программе необходима вся доступная память, то она должна использовать это поле PSP для определения того, сколько памяти она может использовать. Программа также может получать и возвращать память с помощью вызова функции 4Аh. Поле 4   Это команда вызова с атрибутом дистанции FAR диспетчера функций DOS. Следовательно, эта команда содержит полный адрес диспетчера. Этот полный адрес не только указывает на диспетчера, но при этом его смещение указывает, сколько памяти в сегменте команд мы можем использовать (до FFF0, то есть на 16 байт меньше, чем 64 КБайт). Это смещение расположено в PSP со смещением 6, сразу за кодом команды, имеющим смещение 5. Это поле, в отличие от предыдущего, должно работать с большинством многооконных и мультипрограммных систем. Если DOS может предоставить более 64 Кбайт, то определить, на сколько больше, мы можем по полю 2. Поле 5, 6 и 7  Это полные адреса, для трех прерываний по завершению работы, по Ctrl-Break (Ctrl-C) и по ошибке. Если мы хотим использовать свои программы для обработки этих ситуаций, то должны временно изменить эти слова. В конце работы вектора должны быть восстановлены Поле 9   Полный адрес набора строк описания окружающей среды. это набор ASCIIZ строк. каждая строка имеет форму ИМЯ = значение Обычно эта среда содержит по крайней мере имя СОМSPEC (используемое DOS для поиска на диске файла COMMAND.COM). Поле 11   Содержит команды INT 21h и команду возврата управления вызвавшей программе RETF ( RET с дальним аттрибутом дистанции FAR). Таким образом, вместо INT 21h мы можем косвенно через смещение в PSP вызвать эту команду. Поле 13, 14, 15 и 16   Содержит команды INT 21h и команду возврата управления вызвавшей программе RETF ( RET с дальним аттрибутом дистанции FAR). Таким образом, вместо INT 21h мы можем косвенно через смещение в PSP вызвать эту команду. Поле 17, 18   Обеспечивают нашим программам доступ к параметрам командной строки. Поле 17 содержит полную длину строки параметров (которая может быть от 0 до 127), а поле 18 – ее содержимое. Передаваемая строка не содержит имя вызванной программы. Строка начинается с символа, следующего в команде вызова сразу за именем программы; обычно это пробел. Разделители, пробелы и запятые не отбрасываются и не снимаются. Любые параметры переадресации ввода/вывода, такие как < ввод > вывод изымаются DOS и строка реконструируется таким образом, как будто этих элементов не было вообще. В результате этих двух операций программа не может узнать о переадресации стандартного ввода-вывода и не может узнать свое собственное имя. Поле 19  Это область, которая по умолчанию используется DOS для обмена данными с диском (DTA – Disk Transfer Area). Это буфер длиной 128 байт, имеющий смещение 80h. Используется всегда, когда мы пользуемся служебной процедурой DOS для обмена с диском, не задавая в качестве буфера свою собственную область. Команды обработки строк Для обработки строковых данных ассемблер имеет пять команд обработки строк:  movs -  lods -   stos cmps -  scas - переслать один байт или одно слово из одной области памяти в другую; загрузить из памяти один байт в регистр al или одно слово в регистр ax; записать содержимое регистра al или ax в память; сравнить содержимое двух областей памяти, размером в один байт или в одно слово; сравнить содержимое регистра al или ax с содержимым памяти. Префикс rep позволяет этим командам обрабатывать строки любой длины. СВОЙСТВА ОПЕРАЦИЙ НАД СТРОКАМИ Команда Операнды Байт Слово movs es:di, ds:si movsb movsw Lods al,si или ax,si lodsb lodsw Stos di,al или di,ax stosb stosw Cmps si,di cmpsb cmpsw Scas di,al или di,ax scasb scasw rep: ПРЕФИКС ПОВТОРЕНИЯ ЦЕПОЧЕЧНОЙ КОМАНДЫ Несмотря на то, что цепочечные команды имеют отношение к одному байту или одному слову, префикс rep обеспечивает повторение команды несколько раз.  Префикс кодируется непосредственно перед цепочечной командой, например, rep movsb.  Для использования префикса rep необходимо установить начальное значение в регистре cx.  При выполнении цепочечной команды с префиксом rep происходит уменьшение на 1 значения в регистре cx до нуля. Таким образом, можно обрабатывать строки любой длины. Флаг направления определяет направление повторяющейся операции:  для направления слева направо необходимо с помощью команды cld установить флаг df в 0;  для направления справа налево необходимо с помощью команды std установить флаг df в 1. Пример: выполняется пересылка 20 байт из string1 в string2 Предположим, что оба регистра ds и es инициализированы адресом сегмента данных string1 string2 db 20 dup('*') db 20 dup(' ') ... cld mov cx,20 lea di,string2 lea si,string1 rep movsb ;Сброс флага df ;Счетчик на 20 байт ;Адрес области "куда« ;Адрес области "откуда" ;Переслать данные При выполнении команд cmps и scas возможна установка флагов состояния, так чтобы операция могла прекратиться сразу после обнаружения необходимого условия. Ниже приведены модификации префикса rep для этих целей: rep - повторять операцию, пока cx не равно 0; repz или repe повторять операцию, пока флаг zf показывает "равно или ноль". Прекратить операцию при флаге zf, указывающему на не равно или не ноль или при cx равном 0; repne или repnz повторять операцию, пока флаг zf показывает "не равно или не ноль". Прекратить операцию при флаге zf, указывающему на "равно или нуль" или при cx равным 0. Пример проверки командной строки repe mov cmp je xor cld mov mov mov scasb repe dec mov cmpsb CL, ES:80h ; Длина хвоста в PSP CL, ; Длина хвоста=0? install_without_arg ; Да, прогр.запущена без пар. CH, CH ; CX=CL= длина хвоста ; DF=0 - флаг направления вперед DI, 81h ; ES:DI-> начало хвоста в PSP SI, offset key ; DS:SI-> поле key AL, ' ' ; Уберем пробелы из начала хвоста ; Сканируем хвост пока пробелы ; AL - (ES:DI) -> флаги процессора ; повторять пока элементы равны DI ; DI-> на первый символ после пробелов CX, 4 ; ожидаемая длина команды ; Сравниваем введенный хвост с ожидаемым ; (DS:SI)-(ES:DI) -> флаги процессора print_mes_and_exit ; Неизвестная команда flag jne inc . . . ;----------------------------------------------------------------key DB '/off‘ ; команда flag DB 0 Домашнее задание  Написать программу, распечатывающую содержимое PSP ПРЕРЫВАНИЯ Прерывание (interrupt) – это аппаратная функция, вызывающая приостановку операций CPU, запоминание его состояния и выполнение специальной программы, которая называется программой обработки прерывания (interrupt service routine - ISR) или обработчиком прерывания (interrupt handler). Существует три класса прерываний:  внутренние  внешние (аппаратные)  программные Внутренние прерывания инициируются состоянием самого процессора (например, деление на ноль) Внешние – сигналом, подаваемым в CPU другими компонентами вычислительной системы (например, при любом нажатии на клавишу). Программные прерывания – специальной командой INT. Независимо от источника прерывания, последовательность действий, выполняемых CPU по обслуживанию прерывания всегда одинаковая, как для аппаратного, так и для программного прерывания. Микропроцессоры семейства 8086 способны обрабатывать 256 типов прерываний. Каждое прерывание имеет номер от 0 до 255. Начало оперативной памяти от адреса 0000h до 03FFh отводится под векторы прерываний. Вектор прерывания – это 2 слова памяти (4 Байта), в которых хранятся адреса программ обработки прерываний (ISR). В старшее слово записывается сегментный адрес ISR, в младшее слово – смещение ISR, то есть относительный адрес точки входа ISR в сегменте. Вектор 0 располагается, начиная с адреса 0, вектор 1 – с адреса 4, вектор 2 – с адреса 8 и т.д. Вектор с номером N занимает, таким образом, байты с N*4 до N*4+3. Процедура прерывания CPU IP CS IP ISR0 2 CS ISR0 4 IP ISR1 6 CS ISR1 8 IP ISR2 A CS ISR2 Nx4 IP ISRN Nx4+2 CS ISRN Flags 3FC IP ISR255 3FE CS ISR255 400 Old IP New SP Old CS Flags Вектор прерванного процесса Stack Old SP Программа обработки прерывания Вход по прерыванию, например, по команде Сохранение используемых регистров в стеке int Тело ISR Восстановление регистров из стека iret Восстанавливает из стека 3 регистра IP CS Flags Изменение содержимого вектора прерывания Рассмотрим как заполнить вектор «вручную», т.е. без использования функций DOS  Использование функций DOS для изменения содержимого вектора   Сохранение вектора  Заполнение вектора Заполнение вектора Вектор можно изменить непосредственно засылая слова по адресу вектора.  При изменении вектора нужно соблюдать определенные меры предосторожности. Например, если мы изменили только одно слово вектора и возникает прерывание по этому вектору, то это приведет к зависанию программы. Для того, чтобы исключить прерывания в процессе изменения вектора, команды изменяющие вектор должны выполняться при запрещенных прерываниях.  Команда CLI запрещает прерывания, все кроме NMI-немаскируемых прерываний.  Пример заполнения вектора 65h xor ax,ax mov es,ax cli mov word ptr es:65h*4, ;переслать смещение ;запретить прерывания offset new_65h ;точки входа в ;обработчик mov word ptr es:65h*4+2, часть sti ... ... new_65h proc far push ... ... pop iret new_65h endp DS ;и сегментную ;разрешить прерывания Функции DOS для сохранения/изменения вектора прерывания  Получить вектор прерывания Функция 35h Применение: 35h  AH Номер вектора  AL int 21h Возврат ES:BX – содержимое вектора (указатель на программу обработчика)  Изменить вектор прерывания Функция 25h Применение: 25h  AH Номер вектора  AL int 21h В DS:DX – новое содержимое вектора (указатель на программу обработчика) Пример изменения вектора прерывания old_09h ... ... DD ? mov int mov mov mov AX, 3509h ; получить вектор 21h ; прерывания 09h word ptr old_09h, BX ; ES:BX - вектор word ptr old_09h+2, ES DX,offset new_09h ; получить смещение точки ; входа в новый обработчик на DX mov AX, 2509h ; функция установки прерывания ; изменить вектор 09h int 21h ; AL - номер прерыв. ; DS:DX - указатель программы обработки прер. ... ... new_09h: ; точка входа в обработчик Пример code_seg segment assume cs:code_seg, ds:code_seg, ss:code_seg org 100h start: jmp begin line db 2 column db 10 sym db 01h begin: mov AH,25h ;ф-я заполнения вектора прер. mov AL,65h ;номер вектора mov DX,offset new_65h ;смещение обработчика int 21h gogo: int 65h mov AH,02h ;функция позиционирования mov BH,0 ;видеостраница mov DH,line ;строка mov DL,column ;столбец int 10h mov AH,0Ah ;ф-я вывода символа без атрибута mov AL,sym ;символ mov BH,0 ;видеостраница mov CX,60 ;коэффициент повторения int 10h inc sym ;следующий символ inc line ;следующая строка mov ah,08h ;ф-я выв без эха, чувствительная к Ctrl+C int 21h jmp gogo new_65h proc near mov AH,06h ;функция задания окна mov AL,0 ;режим создания (нет прокрутки) mov BH,1bh ;атрибут всех символов в окне ;(светло-бирюзовые символы, синий фон) mov CX,0 ;левый верхний угол 0,0 mov DH,24 ;нижняя Y-координата mov DL,79 ;правая X-координата int 10h iret new_65h endp code_seg ends end start Табличные вызовы подпрограмм Для вызова функции DOS в AH заносится номер функции и с помощью int 21h вызывается диспетчер DOS. Диспетчер извлекает из AH номер функции и активизирует по этому номеру соответствующую программу из числа функций DOS. Рассмотрим упрощенную имитацию диспетчера DOS. В нашей программе должен быть диспетчер, вызываемый с помощью прерывания и передающий управление подпрограмме с заданным в AH номером. Адрес диспетчера внесем в один из свободных векторов прерывания. Номер функции пересылается из AH в регистр BX, который в дальнейшем используется в качестве индексного. Сдвиг BX соответствует умножению на 2. Теперь BX - индекс, в таблице адресов addr_tbl, в которой записаны смещения (относительные адреса) подпрограмм в порядке, определяющем их номера. jmp start ; Диспетчер прерывания 65h new_65h: push bx push dx mov bl, ah mov bh, 0 shl bx, 1 ; Лог. сдв. влево на один разряд call add_tbl[bx]; pop dx pop bx iret ;Подпрограммы-функции Продолжение sub0: программы... mov ah, 9 lea dx, mes0 int 21h ret ... ... ... sub4: mov ah, 9 lea dx, mes4 int 21h ret start: mov ax, 2565h ; ф-ия заполнения вектора ; прер. int 65h mov dx, offset new_65h int 21h Продолжение программы... ;Последовательно вызываем подпрограммы mov ah, int 65h mov ah, 1 int 65h ... ... ... mov ah, 4 int 65h mov ax, 4c00h ; exit int 21h Продолжение программы... ;Таблица адресов и подпрограмм add_tbl dw sub0 dw sub1 ... ... ... dw sub4 ;Сообщения mes0 db ‘Отработала подпрограмма 0’, 13,10,’$’ ... ... ... mes4 db ‘Отработала подпрограмма 4’, 13,10,’$’ Резидентные программы TSR (Terminate and Stay Resident)    Любая TSR программа содержит один или несколько взаимодействующих друг с другом обработчиков прерываний, которые обеспечивают запуск программы и выполняют служебные функции. После прерывания регистры DS, ES, SS содержат прежние значения (какими они были до прерывания), поэтому внутри обработчика нужно использовать адресацию относительно CS. Чаще всего резидентные программы не полностью заменяют имеющиеся обработчики прерываний, а лишь дополняют их. Формат TSR программы entry: ; ; ; ; ; ; boot: jmp org boot 100h Обработчик прерывания (резидентная часть) вызов старого обработчика (с возвратом или без возврата) ; часть инициализации ; изменение вектора прерывания mov dx, offset boot int 27h end entry Функция DOS - завершить программу и оставить в памяти  int 27h CS DX - завершить программу и оставить резидентной сегментный адрес PSP смещение первого байта освобождаемой памяти Вызов старого обработчика  Передача управления без возврата. Передать управление исходному обработчику можно: jmp  Передача управления с возвратом. (Имитация прерывания по старому вектору): pushf call  dword ptr [old_int_vect] dword ptr [old_int_vect] Это для iret, которая извлекает из стека три слова Здесь old_int_vect - двойное слово, в котором сохранен исходный вектор прерывания. old_int_vect DD ? Защита резидентной программы от повторной загрузки    Если в резидентной программе нет защиты от повторной загрузки, то при повторном её запуске станет резидентной её вторая копия. И т.д. этот процесс может продолжаться до тех пор, пока не будет исчерпана оперативная память Наиболее распространенным методом защиты резидентной программы от её повторной установки является использование мультиплексного прерывания 2Fh, специально предназначенного для взаимодействия с резидентными программами Мультиплексное прерывание 2Fh Вызов: AH  номер мультиплексного процесса (идентифицирует обработчик прерывания) 00H-7FH Резерв DOS 80h-B7h доступны B8h-8Fh резерв для сетей C0h-FFh доступны для прикладных программ В частности, номера 00 и 01 закреплены за резидентной программой DOS print.com 02h рез. порция assign 10h рез порция share Al номер функции Al 00h - дать статус установки процесса Возвращает: Al статус установки 00h не установлен - можно устанавливать 01h не установлен - нельзя устанавливать FFh установлен Обработка прерывания 2Fh в резидентной программе     Для того, чтобы резидентная программа могла отозваться на int 2Fh, в ней должен иметься обработчик этого прерывания. Через этот обработчик может быть осуществлена не только проверка на повторную инициализацию, но и вообще связь с резидентной программой - смена режима её работы или получения от нее каких-то параметров. Задания действий осуществляются с помощью функции, заданной в AL. Таким образом обработчик должен прежде всего проверить номер процесса в AH и при обнаружении своего номера проанализировать AL и выполнить затребованные действия, после чего с помощью iret передать управление вызвавшей программе. Если обработчик обнаружил в AH - номер чужого процесса, он должен командой jmp передать управление по цепочке тому обработчику, адрес которого был ранее в векторе 2Fh. В результате вызов int 2fh из любой программы будет проходить по цепочке через все загруженные программы, пока не достигнет «своей» программы или не вернет управление в вызвавшую программу через обработчик DOS, который, очевидно, всегда будет самым последним в цепочке Альтернативное мультиплексное прерывание int 2Dh int 2Dh AH - мультиплексный номер AL - функция 00h - проверка инсталляции Возврат al=0 -не установлен al=ffh установлен cx-версия dx:di - строка сигнатуры al=02h - выгрузка Программа не должна использовать мультиплексный номер.  Программа должна сканировать мультиплексные номера с 00h по FFh, запомнить первый свободный, т.е номер процесса, который не инсталлирован.  Программа должна сравнивать 16 байт сигнатуры для всех мультиплексных номеров, которые используются с целью определения установлена ли программа на этом номере. Если не установлена, то берется первый свободный номер.  Формат сигнатуры: offset size 00h 08h 10h 8 bytes 8bytes 64bytes descriptor имя произв имя прогр. asciz опсание продукта Пример использования прерывания 2Fh int_2Fh_vector DD ? ... int_2Fh proc far cmp AX, 0B700h ; или 0C700 jne Pass_2Fh mov AL, 0FFh iret Pass_2Fh: jmp dword ptr CS:[int_2fh_vector] int_2Fh endp ;====================================== begin: mov AX,0B700h ; установить статус процесса мультиплексного прер. int 2Fh cmp AL,0 jz not_installed lea DX,msg call print int 20h msg DB ‘Программа уже инициализирована’, 13, 10, ‘$’ not_installed: Выгрузка резидентной программы В DOS отсутствуют средства выгрузки резидентных программ. Единственный способ - перезагрузка компьютера. Правда есть утилиты, которые позволяют удалять резидентные программы. Резидентные программы должны иметь встроенные средства выгрузки. Рассмотрим пример. Пусть последовательно загружаются в память три резидентные программы A,B,C. Перед изменением адреса прерывания программа сохраняет адрес обработчика, а затем вызывают его в процессе своей работы. Программа A перехватывает прерывание 09h и 21h Программа B перехватывает прерывание 16h и 21h Программа C перехватывает прерывание 09h После этого программа A удаляется из памяти До удаления: 09h vect Адр. обр прогр C 16h vect Адр. обр прогр B 21h vect Адр. обр прогр B Int 09h vect Адр. обр прер. 09h BIOS Int 21h vect Адр. обр прер. 21h DOS Int 16h vect Адр. обр прер. 16h BIOS Int 21h vect Адр. обр прер. 21h прогр. A Int 09h vect Адр. обр прер. 09h прогр. A Программа A Программа B Программа C После удаления: 09h vect Адр. обр прер. 09h BIOS 16h vect Адр. обр прер. 16h прогр. B 21h vect Адр. обр прер. 21h DOS Int 16h vect Адр. обр прер. 16h BIOS Int 21h vect Адр. обр прер. 21h прогр. A (висячая ссылка) Int 09h vect Адр. обр прер. 09h прогр. A Программа B (висячая ссылка) Программа C Функция Освободить память int 21h AH=49h ES  сегментный адрес освобождаемого блока памяти возврат: CF=0 ошибок нет CF=1 AX=9 Пример процедуры выгрузки из памяти remove mov mov int mov cmp jne cmp jne mov int mov cmp jne cmp je not_remove: proc CX,CS AX, 3509h 21h DX, ES CX, DX not_remove BX, offset not_remove AX, 3521h 21h DX, ES CX, DX not_remove BX, offset uninstall ret ;проверить вектор 09h int_09h ;проверить вектор 21h inr_21h uninstall: push lds ; ; mov mov mov int lds mov int pop push pop mov int ret remove DS DX, int_09h_vect DX, DS, AX, 21h DX, AX, 21h DS CS ES AH, 21h ; восстановить 09h ; Эта команда эквивалентна ; следующим двум word ptr int_09h_vect word ptr int_09h_vect+2 2509h int_21h_vect 2521h 49h endp Переключение стека в резидентной программе     При реализации процедуры прерывания (аппаратного или программного) CPU сохраняет в стеке прерванной задачи регистр флагов, сегментный регистр, регистр CS и IP и загружает из вектора прерывания в регистры CS и IP двухсловный адрес обр-ка прер-ния. Все остальные регистры хранят ту информацию, которая в них была на момент прерывания. Для того, чтобы не разрушать прерванную задачу, в самом начале обработчика прерывания следует сохранить все используемые в обработчике регистры, а перед командой iret - восстановить их. Это относится и к сегментным регистрам и к РОН. Все команды обращения к памяти используют по умолчанию в качестве сегментного регистра - регистр DS. Если при переходе в обработчик не выполнить настройку DS на сегмент обработчика, то команды вида: mov AX, mem mov BX, [SI] будут обращаться к случайным ячейкам прерванной задачи, что, возможно, приведет к разрушению и этой задачи, и обработчика. Если нежелательно перенастраивать регистр DS, то в командах работы с памятью следует использовать замену регистра: mov AX, CS:mem mov BX, CS:[SI]     Особая ситуация возникает со стеком . При переходе в обработчик регистры SS и SP настроены на стек прерванной задачи. Если этот стек имеет достаточный объем, то обработчик его может использовать, а если нет - переполнение стека может привести к разрушению прерванной программы. Поэтому надежнее в обработчике прерывания иметь собственный стек. Если TSR программа «паразитирует» на чужом стеке, то в этом случае использование стека должно быть минимальным. Смена стека требует запоминания кадра стека (содержимого SS и SP) в ячейках памяти отведенной обработчику, занесения в SS и SP новых значений и восстановления старого кадра перед выходом из обработчика. Естественно, что для стека должен быть выделен свободный объем (необходимый для запоминания своих данных, а может быть и чужих, от программ, «паразитирующих» на чужом стеке). Если резидентная программа не допускает повторной активизации в процессе своей работы, то можно не делать проверку переключения стека, и смена стека может быть осуществлена следующим образом: org begin 100h start: jmp ss_seg dw ss_offs dw mem dw . . new_handler proc far mov cs:ss_seg,ss ;сохр.кадра стека прерванной задачи mov cs:ss_offs,sp cli ;запрет прерываний mov cs:mem,cs ;настроим ss на наш сегмент mov ss,cs:mem mov sp,offset end_res ;настроим sp sti ;разрешим прерывания ; теперь работаем на стеке резидентной программы . . ;в конце резидентной части: stack_area dw 256 dup (?) new_handler endp end_res=$     Процедура обработчика прерывания начинается с сохранения кадра стека прерванной задачи. Адресация ячеек выполняется через CS, поскольку DS еще указывает на сегмент данных вызвавшей программы. Установка нового кадра стека всегда выполняется при запрещенных прерываниях, т.к. если аппаратное прерывание произойдет между командами заполнения SS и SP, вектор прерванного процесса будет сохранен в случайной ячейке памяти. Заполнить сегментный стека можно и так: push CS pop SS Однако это выполняется на стеке прерванной программы, приведенный же пример не затрагивает ни стека прерванной задачи, ни регистр ax, ни других регистров. Т.к. команда mov SS, CS запрещена, то содержимое cs копируется в ss через ячейку памяти mem. Команда mov SP, offset end_res заносит адрес для первого стека, место под которым выделено в самом конце резидентной части обработчика. Под стек отведено 256 слов.   При запуске программы на выполнение DOS находит свободную область памяти подходящего размера. В начале программы создается префикс программного сегмента (PSP) размером в 256 байт. Сама программа загружается вслед за PSP. Кроме того, DOS передает программе копию среды. Размер среды от 160 байт для MS DOS 3.3 и выше. Сегментный адрес среды помещается в PSP по смещению 2ch. Резидентные программы практически никогда не используют среду DOS, занимаемую ею память можно освободить с помощью функции 49h. mov ES, word ptr DS:[2CH] ;загрузить сегментный адрес среды в es mov AH, 49h ;и освободить память int 21h Резидентная программа не нуждается и в PSP. Младшая часть PSP (до смещения 5ch) используется DOS и в последний раз потребуется при выполнении функции 31h или прерывания 27h. В дальнейшем DOS будет использовать PSP прерванной программы.   Некоторые TSR программы используют PSP программы, например, пересылают резидентную часть программы в PSP c помощью команды movsb, уменьшая тем самым размер резидентной позиции. Однако, надежнее, проще и целесообразнее найти применение PSP в резидентной программе. Например, использовав его как буфер ввод-вывод или разместив в нем собственный стек. Последнее выполняется следующим образом: вместо mov SP, offset end-res mov SP, offset start При этом получаем стек глубиной 256 байт или 128 слов, т.е. все PSP Обработчик прерываний от таймера   Большому количеству TSR программ необходимы постоянные по времени проверки ресурсов системы или осуществление активизации некоторых процессов. Подобные действия может обеспечить обработчик прерываний от таймера. Векторы прерываний. Прер. 20 таймера 08h 1Сh Заглушка BIOS iret . . iret . . . Int 1Сh . iret iret Прикладная обработка Программа BIOS отсчета времени Контроллер прерываний и его программирование  Если необходимо написать обработчик аппаратного прерывания – то нужно выполнить все необходимые действия:       аппаратура, от которой пришло прерывание; микросхемы контроллера прерываний. Сигналы прерываний поступают от ВУ через контроллер прерываний (микросхема Intel 8259A) Основное назначение контроллера – направление сигналов запросов прерываний от восьми устройств на единств.вход прерываний процессора Контроллер передает в процессор номер вектора по линиям данных. Сигнал INT поступающий на одноименный вход СРU инициирует процедуру прерывания. Организация аппаратных прерываний в IBM РС/ХТ IRQ0 IRQ1 IRQ2 IRQ3 КОНТР ОЛЛЕР ПРЕРЫ ВАНИЙ INT СРU vector IRQ4 IRQ5 IRQ6 IRQ7 Баз. вектор – 8 Порты 20h, 21h IRQ - Interrupt Request Запрос прерывания Формирование вектора прерывания 1 IRQ0 1 1 IRQ1 09h клавиатура 1 1 IRQ2 0Ah Резерв 1 1 1 IRQ3 0Bh Сом2 1 1 IRQ4 0Ch Сом1 1 1 1 IRQ5 0Dh Жесткий диск 1 1 1 IRQ6 0Eh Гибкий диск 1 1 1 1 IRQ7 0Fh LPT1 Базовый вектор 08h таймер В IBM PC/AT 2 контроллера прерываний IRQ8 IRQ9 IRQ10 IRQ11 IRQ12 IRQ13 КОНТР ОЛЛЕР ПРЕРЫ ВАНИЙ Ведо мый IRQ0 IRQ1 IRQ3 IRQ4 IRQ5 IRQ14 IRQ6 IRQ15 IRQ7 Баз.вектор – 70h Порты А0h, А1h КОНТР ОЛЛЕР ПРЕРЫ ВАНИЙ INT СРU vector Веду щий Базовый вектор - 8 Порты 20h, 21h Соответствие векторов прерываний устройствам компьютера Прерывание IRQ  IRQ1 IRQ2 IRQ8 IRQ9 IRQ10 IRQ11 IRQ12 IRQ13 IRQ14 IRQ15 IRQ3 IRQ4 IRQ5 IRQ6 IRQ7 Вектор 8h 9h Ah 70h 71h 72h 73h 74h 75h 76h 77h Bh Ch Dh Eh Fh Устройство Таймер Клавиатура Вход от ведомого Клапан микросхемы часы realtime Программно перенапр. на IRQ2 (int OAh) Резерв -«Мышь (PS/2) Сопроцессор Жесткий диск Резерв Сом 2 Сом 1 Принтер LPT2 Гибкий диск LPT1 Структура контроллера CPU INT IF INTA IRQ0 IRQ1 1-0 IRQ2 1 x IRQ3 x IRQ4 1 x IRQ5 x IRQ6 x IRQ7 x Регистр маски IMR Port 21h Схема анализа приоритетов Port 20h Регистр Запросов IRR Port 20h x 1-0 Регистр обслуживаемых запросов ISR Port 20h EOI Структура программы обработки аппаратного прерывания IRQ1 Запрещены все вложенные прерывания, независимо от их приоритетов (IRQ  - IRQ7) sti Разрешены только вложенные прерывания с более высокими приоритетами IRQ EOI Разрешены все вложенные прерывания, независимо от их приоритетов (IRQ0 - IRQ7) iret Обработчик прерываний, допускающий вложенность прерываний IRQi STI Возможны прерывания более высоких уровней IRQØ – IRQ(i-1) Interrupt IRQ Ø,..,i,i+1,.. Возможны прерывания всех уровней MOV AL, 20h ОUT 20h, AL IRET EOI Обработчик прерываний, не допускающий вложенности прерываний IRQi STI Возможны прерывания более высоких уровней IRQØ – IRQ(i-1) Запрещены все прерывания CLI MOV AL, 20h ОUT 20h, AL IRET EOI Примеры программирования контроллера прерывания  mov AL, 20h out 20h, AL out A0h, AL AL, 21h AL, 1 21h, AL Запросы на прерывания, поступающие в ведущий контроллер IRQ - IRQ7 блокируют только ведущий контроллер. Однако запросы на прерывание, поступающие в ведомый контроллер - (IRQ8-IRQ15) , блокируют уровни низших приоритетов в ведомом и IRQ2 - IRQ7 – в ведущем контроллере. Поэтому в программах обработки прерываний уровней 8…15 следует предусматривать посылку команды конца прерываний в оба контроллера  in or out ; прочитать текущую маску ; установить в 1 разряд  рег-ра IMR ; вернуть в IMR  in AL, 21h ; прочитать текущую маску and AL, 0FEh ; сбросить бит в  out 21h, AL ; вернуть в IMR Выполнение этих команд приведет к остановке системного таймера. Выполнение этих команд приведет к восстановлениб работы системного таймера. Резидентный обработчик прерываний от клавиатуры с подключением до системного Аппарат. прерывание Отпускаие или нажатие клавиши Контроллер прерываний Контроллер клавиатуры CPU Адрес системного обработчика из вектора 09h 8048 Порт 60h Int 09h Скен-код Кольцевой буфер ввода (16 слов) Байт флагов клавиатуры 40h:17h 40h:1Eh Адрес головного символа 40h:1Ah Скен Скен ASCII ASCII Адрес хвостового символа 40h:1Ch Программа пользователя Программный запрос на ввод с клавиатуры 40h:3Сh (1E + 20) – 1 = 3E – 2 = 3C Байт флагов клавиатуры Статус Ins Caps Lock Num Lock Scroll Lock Сост.Alt Ctrl Shift left Shift right КВ-FLAG 40h:17h или можно определить КВ-FLAG следующим образом: RIGHT-SHIFT EQU клавиша правого шифта нажата LEFT-SHIFT EQU клавиша левого шифта нажата 00000001B; 00000010B; Клавиша SysRq нажата -- // --Caps Lock -- // ---- // --Num Lock -- // ---- // --Scroll Lock -- // --Правая Alt нажата Правая Ctrl нажата Левая Alt нажата Левая Ctrl нажата Кольцевой буфер ввода 40h:1Аh BUFFER_HEAD 40h:1Сh BUFFER_TAIL 40h:1Eh КВ_BUFFER DW ? ; указатель головного симв. DW ? ; указатель хвостового симв. ; HEAD = TAIL - указывает, что буфер пустой DW 16 DUP (?) ;кольцевой буфер Пример обработчика прерывания 09h с подключением до системного ; поле данных резидентной секции old_09h DD ? new_09h proc far push АХ ; Сохраним используемый регистр in AL, 60h ; Введем скен-код сmp AL, 44h ; Это скен-код (F10)? je hotkey ; Да роp АХ ; Восстановим АХ jmp dword ptr CS:[old_09h] ; В системный обработчик без возврата hotkey: ; Разрешим дальнейшую работу клавиатуры in AL, 61h ; Введем содержимое порта В or AL, 80h ; Установим старший бит jmp $+2 out 61h, AL ; И вернем в порт В and AL, 7Fh ; Снова разрешим работу клавиатуры out 61h, AL ; Сбросив старший бит в порту В ;Пошлем приказ EOI mov AL, 20h out 20h, AL рор АХ iret new_09h endp Обработка горячей клавиши (Alt)/(F10) new_09h je exit1: gogo: proc push in сmp gogo роp far АХ AL, AL, jmp dword push mov mov mov рор сmр je jmp АХ ; ; ; ; ; Сохраним используемый регистр Введем скен-код Это скен-код (F10)? Да Восстановим АХ ptr CS:[old_09h] ES AХ, 40h ES, АХ AL, ES: 17h ES AL, 08h hotkey exit1 ; ; ; ; ; ; ; ; ; В системный обработчик без возврата Сохраним ES Настроим ES на начало Данных BIOS Получим байт флагов клавиатуры Восстановим ES – он больше не нужен (Alt) уже нажата? Да Нет, в системный обработчик 60h 44h hotkey: ; Разрешим дальнейшую работу клавиатуры in AL, 61h or AL, 80h jmp $+2 out 61h, AL and AL, 7Fh out 61h, AL ;Пошлем приказ EOI mov AL, 20h out 20h, AL рор АХ iret new_09h endp ; Введем содержимое порта В ; Установим старший бит ; И вернем в порт В ; Снова разрешим работу клавиатуры ; Сбросив старший бит в порту В Резидентный обработчик прерывания от клавиатуры с подключением после системного обработчика CODE_SEG ASSUME SEGMENT CS:CODE_SEG,DS:code_seg ORG 100H START: JMP BEGIN int_2Fh_vector DD ? old_09h DD ? ;============================================================================= ; ;============================================================================= new_09h proc far pushf ; В системный обработчик call push push push mov mov mov dec dec cmp jae mov dword ptr CS:[old_09h] ; с возвратом AX BX ES AX,40h ; Настроим ES на сегментный ES,AX ; адрес области данных BIOS BX,ES:[lCh] ; Адрес нового хвоста BX ; Сместимся назад к последнему BX ; введенному символу BX,lEh ; Хвост не вышел за пределы буфера? go ; Нет, значит он был где-то внутри буфера BX,3Ch ; Хвост после вычитания 2 вышел за пределы буфера, ; сл-но он был в самом начале, а последний введенный ; символ находится в самом конце буфера go: mov AX,ES:[BX] ; Получим последний символ из буфера cmp AX,1600h ; Был введен расширенный код ASCII сочетания Alt/U? jne go__out ; Нет mov word PTR ES:[BX],OODAh ; Да, заменим код в буфере на код уголка go_out: pop ES pop BX pop AX iret new_09h endp ;============================================================================= int_2Fh proc far cmp AX,0C700h jne pass_2Fh mov AL,OFFh iret pass_2Fh: jmp dword PTR CS:[int_2Fh_vector] int_2Fh endp ;============================================================================= begin: mov AX,0C700h ; AH=OC7h номер процесса C7h ; AL=OOh -дать статус установки процесса int 2Fh ; мультиплексное прерывание cmp AL, 0 jz not_installed ; возвращает AL=0 если не установлена lea DX, msg call print int 20h msg DB 'Уже установлена',13,10,'$' not_instailed: mov AX, 352Fh ; получить вектор int 21h ; прерывания 2Fh mov word ptr int_2Fh_vector,BX ; ES:BX - вектор mov word ptr int_2Fh_vector+2,ES mov DX, offset int_2Fh ; получить смещение точки входа в новый ; обработчик на DX mov AX, 252Fh ; функция установки прерывания ; изменить вектор 2Fh int 21h ; AL - номер прерыв. DS:DX - указатель программы обработки прер. mov AX,3509h ; получить вектор int 21h ; прерывания 09h mov word ptr old_09h, BX ; ES:BX - вектор mov word ptr old_09h+2, ES ; mov DX, offset new_09h ; получить смещение точки входа в новый обработчик на DX mov AX, 2509h ; функция установки прерывания изменить вектор 09h int 21h ; AL - номер прерыв. DS:DX - указатель программы обработки прер. ;-----------------------------------------------------------------------------mov DX,offset begin ; оставить программу ... int 27h ; ... резидентной и выйти ;============================================================================= PRINT PROC NEAR MOV АН,09H INT 21H RET PRINT ENDP ;============================================================================= CODE_SEG ENDS END START Состояние кольцевого буфера Пусть перед вводом данного символа буфер был пуст 40h:1Еh Голова 40h:1Аh ... ... Мусор Мусор ... ... Хвост 40h:1Сh 40h:ЗСh Это адрес указателя, а не его содержимое Фактически в слове, на которое указывают оба указателя, находится код символа, введенного ранее и уже изъятого программой из буфера Состояние кольцевого буфера после ввода символа 40h:1Еh Голова 40h:1Аh ... ... scan ASCII ... ... Хвост 40h:1Сh 40h:ЗСh 40h:1Еh Хвост 40h:1Сh ... ... ... ... scan ASCII Голова 40h:1Аh 40h:ЗСh В программе после вычитания 2 из адреса хвостового элемента, проверяется находится ли полученное значение в пределах буфера. Если оно равно или больше 1Еh, команда jae выполняет переход на продолжение программы. Если полученное значение меньше 1Еh, то это значит, что хвостовой указатель указывает на самое начало буфера, а занесенный только что в буфер код находится в самом его конце Резидентный обработчик прерываний от клавиатуры с подключением как до, так и после системного CODE_SEG SEGMENT ASSUME CS:CODE_SEG,DS:code_seg ORG 100H START: JMP BEGIN int_2Fh_vector DD ? old_09h DD ? tail DW new_09h proc far push AX push ES mov AX, 40h ; Настроим ES на сегментный mov ES, AX ; адрес области данных BIOS mov AX, ES:[1Ch] ; Сохраним адрес хвоста перед обработкой mov CS:tail, AX pop ES pop AX pushf ; В системный обработчик call CS:old_09h ; с возвратом push AX push BX push ES mov AX, 40h ; Настроим ES на сегментный mov ES, AX ; адрес области данных BIOS mov BX, CS:tail ; Адрес нового хвоста cmp BX, ES:[1Ch] ; Хвост сместился? jne go_out ; нет – на выход mov AX, ES:[BX] ; Получим последний символ из буфера cmp AX, 1600h ; Был введен расширенный код ASCII сочетания Alt/U? jne go_out ; Нет mov word PTR ES:[BX],OODAh ; Да, заменим код в буфере на код уголка go_out: pop ES pop pop iret new_09h endp int_2Fh cmp jne mov iret pass_2Fh: jmp int_2Fh endp begin: mov int cmp jz BX AX proc far AX,0C700h pass_2Fh AL,OFFh dword PTR CS:[int_2Fh_vector] AX, 0C700h 2Fh AL, not_installed ; AH=OC7h номер процесса C7h ; AL=OOh -дать статус установки процесса ; мультиплексное прерывание ; возвращает AL=0 если не установлена lea DX,msg call print int 20h msg DB 'Уже установлена',13,10,'$' not_instailed: mov AX, 352Fh ; получить вектор int 21h ; прерывания 2Fh mov word ptr int_2Fh_vector,BX ; ES:BX - вектор mov word ptr int_2Fh_vector+2,ES mov DX, offset int_2Fh ; получить смещение точки входа в новый ; обработчик на DX mov AX,252Fh ; функция установки прерывания ; изменить вектор 2Fh int 21h ; AL - номер прерыв. DS:DX - указатель программы обработки прер. mov int mov mov mov mov AX, 3509h 21h word ptr old_09h, BX word ptr old_09h+2 ,ES DX, offset new_09h AX, 2509h ; получить вектор ; прерывания 09h ; ES:BX - вектор ; ; получить смещение точки входа в новый обработчик на DX ; функция установки прерывания ; изменить вектор 09h int 21h ; AL - номер прерыв. DS:DX - указатель программы обработки прер. ;-----------------------------------------------------------------------------mov DX, offset begin ; оставить программу ... int 27h ; ... резидентной и выйти ;============================================================================= ;============================================================================= PRINT PROC NEAR MOV АН,09H INT 21H RET PRINT ENDP ;============================================================================= CODE_SEG ENDS END START Использование памяти BIOS Положение Длина Описание 40:10 Байт Установленная аппаратура 1 40:11 Байт Установленная аппаратура 2 40:12 Байт Состояние после включения питания 40:13 Слово Размер памяти 40:15 Слово Резерв 40:17 Байт Байт флагов клавиатуры 1 40:18 Байт Байт флагов клавиатуры 2 40:1А Слово Адрес головного символа 40:1С Слово Адрес хвостового символа 40:1Е 32 байта Кольцевой буфер клавиатуры 40:49 Байт Режим дисплея 40:4А Слово Число колонок 40:4С Слово Длина буфера регенерации в байтах 40:4Е Слово Адрес буфера регенерации Использование памяти BIOS (продолжение) Положение Длина Описание 40:50 Слово Позиция курсора на стр. 1 40:52 Слово « 2 40:54 Слово « 3 40:56 Слово « 4 40:58 Слово « 5 40:5А Слово « 6 40:5С Слово « 7 40:5Е Слово « 8 40:60 Слово Тип курсора 40:62 Байт Текущая строка изображения 40:63 Слово Базовый адрес видеоконтроллера . . . 40:6С Слово Счетчик таймера 40:70 Байт 40:71 Байт Сост.клав.Break Режимы дисплея Номер Тип Макс. цветов Формат текста Макс. Страниц Нач. адрес Т 16 40х25 8 В8000 1 Т 16 40х25 8 В8000 2 Т 16 80х25 4 8 8 В8000 3 Т 16 80х25 4 8 8 В8000 4 Г 4 320х200 40х25 1 В8000 5 Г 4 320х200 40х25 1 В8000 6 Г 2 640х200 80х25 1 В8000 7 Т Моно 80х25 8 Г 16 160х200 20х25 1 В0000 9 Г 16 320х200 40х25 1 В0000 А Г 4 640х200 80х25 1 В0000 D Г 16 320х100 40х25 8 А0000 Е Г 16 640х200 80х25 4 “ F Г Моно 640х350 80х25 2 “ 10 Г 16 640х350 80х25 2 “ 1. 8 В0000 Функции int 10h 00h установить видео режим 01h установить размер и форму курсора 02h установить позицию курсора 03h читать позицию курсора 04h читать световое перо 05h выбрать активную страницу дисплея 06h листать окно вверх (или очистить) 07h листать окно вниз 08h читать символ/атрибут 09h писать символ/атрибут 0Ah писать символ 0Bh выбрать палитру/цвет бордюра 0Ch писать графическую точку 0Dh читать графическую точку 0Eh писать символ в режиме TTY 0Fh читать видео режим 10h EGA уст ановить палитру 11h EGA генератор символов 12h EGA специальные функции 13h писать строку (только AT + EGA ) Атрибут символа 7 6 5 4 Яркость фона или мерцание символа Цвет фона Яркость символа Цвет символа 3 2 1 Цвет символа Биты 0-3 Цвет черный 1 синий 2 зеленый 3 бирюзовый 4 красный 5 фиолетовый 6 коричневый 7 белый 8 серый 9 голубой А салатовый В светло-бирюзовый С розовый D светло-фиолетовый E желтый F ярко-белый Биты 4-6 цвет фона под символом. Бит 7 – в зависимости от режима видеоодаптера определяет либо яркость фона под данным символом (тогда фон принимает 16 цветов), либо мерцание символа. Так, в режиме мерцания значения старшего полубайта атрибута 8h обозначает не серый фон, а черный при мерцающем символе. Сh- не розовый, а красный Очистим экран, наложив на него черно-белое окно mov mov AH, Al, 06h mov BH, 07h mov mov mov mov int CH, CL, DH, DL, 10h 24 79 ; ; ; ; ; ; ; ; ; ; функция задания окна режим создания (не прокрутка) атрибут всех символов в окне – ч/б верхняя Y – коорд. левая Х – коорд. нижняя Y – коорд. правая X – коорд. прер. BIOS. 0,0 24 y 79 x Выведем на экран цветное окно mov mov mov mov mov mov mov int AH, AL, BH, CH, CL, DH, DL, 10h 06h 1Eh 5 40 9 75 ; функция задания окна ; режим создания (не прокрутки) ; атрибут желтый по синему ; верхняя Y – коорд. ; левая X – коорд. ; нижняя Y – коорд. ; правая X – коорд. ; прер. BIOS Позиционируем курсор mov mov mov mov Int AH, BH, DH, DL, 10h 02h 7 45 ; функция позиционирования ; видеостраница ; строка ; столбец Вывод строки символов в окно без задания атрибутов (т.е. с атрибутами окна) metka: mov mov mov mov inc Int Loop CX, BX, AH, AL, BX 10h metka len1 offset 0Eh [Bx] ; длина строки mes1 ; адрес строки символа ; вывод одного символа в реж. телетайпа ; символ в AL ; сдвиг по строке ; Строка вне окна, с указанием атрибутов символов mov AH, 13h ; функция вывода строки mov AL, ; режим (атрибут в BL) mov BH, ; видеостраница mov BL, 04h ; атрибут всех символов mov CX, len2 ; длина строки mov DH, 16 ; начало позиции - строка mov DL, 25 ; начало позиции - столбец push DS ; настройка ЕS на наш сегм. pop ES ; данные mov BP, offset mes2 ; ES:BP – выв. стр. Int 10h ; Позицируем курсор в начало посл. строки экрана mov AH, 02h ; функция позиционирования mov BH, ; видеострока mov DH, 24 ; строка mov DL, ; столбец Int 10h mes1 DB 16,’Cтрока, выведенная в окно’,17 len1 = $-mes1 mes2 DB 22,22,22,’Строка, выведенная вне окна’,22,22,22 len2 =$-mes2 Работа с видеобуфером См. Слайд «Распределение адресного пространства в DOS» Текстовый видеобуфер адаптера EGA включает 8 видеостраниц и занимает 32Кб от сегментного адреса B800h. Начинается он с видеостраницы 0, адрес которой B8000h. Объем видеостраниц 4Кб. Видеостраница Начальный адрес В8000 1 В9000 2 ВА000 3 ВВ000 4 BC000 5 BD000 6 BE000 7 BF000 До BFFFF, следующий адрес C0000h Логическая организация текстового видеобуфера B800h:00 Символ B800h:01 Атрибут знакоместо 0 B800h:02 Символ B800h:03 Атрибут знакоместо 1 B800h:04… Символ … знаком... Принципы работы с видеобуфером     2-х байтовые коды символов записываются в видеобуфер в том порядке, в каком они должны появляться на экране, т.е. первые 80 двухбайтовых полей - соответствуют первой строке, вторые 80 - второй строке и т. д. Таким образом, переход на следующую строку осуществляется не с помощью управляющих кодов возврата каретки или перевода строки, а с размещением кодов символа в другом месте буфера, в полях, соответствующих следующей строке. Вообще при формировании изображения непосредственно в видеобуфере, в обход программ DOS и BIOS, все управляющие коды ASCII теряют свои управляющие функции и отображаются в виде соответствующих им символов. Трактовка же кодов 10,13 - ПС и ВК- выполняется программами DOS или BIOS, которые в данном случае не активизируются. Пример программы непосредственной работы с видеобуфером mov mov mov mov mov mov mov AX, ES, BX, AL, 0B800h AX 80*2*5 ’*’ ; сегментный адрес видеобуфера ; загрузка в ES ; смещение в видеобуфере(в байтах) ; код ASCII символа в AL ; соответствует первому (четному) ; байту знакоместа AH, 0Eh ; атрибут- желтый на черном ; соответствует второму (нечетному) ; байту знакоместа - код атрибута ES:[BX], AX ; запись в видеобуфер ES:[BX+162],0B0Fh ; цвет светлобирюзовый по черному, ; символ с кодом ASCII Fh Выражение 80*2*5 – смещение от начала видеобуфера первого байта строки 5 Запишем строку в видеобуфер push CS pop DS mov AX, mov ES, mov SI, Mov DI, mov CX, cld rep movsb ;Данные msg DB msglen=$-msg ;DS на наш сегмент ; команд 0B800h ; AX ;ES-> на видеобуфер offset msg ;SI= адрес источника 80*2*12+37*2 ;DI= адрес приёмника msglen ;CX-число пересылаемых битов ; сброс DF - вперед ; пересылка в цикле ‘П’,1Eh,’р’,1Eh,’и’,1Eh,’в’,1Eh,’е’,1Eh,’т’,1Eh Сдвиг от начала видеобуфера составляет 12 строк по 80 символов + 37 символов Если для всех символов атрибут одинаковый, то программа может быть организована следующим образом ; DS на наш сегмент ; ES на строку 0 видеобуфера mov DI, 80*2*5 ; начальное смещение на экране ; Будем переносить байт за байтом ; на экран, вставляя между ; кодами ASCII биты атрибута mov CX, str_len ; длина строки mov SI, offset str ; смещение исходной строки cld ; DF=0 вперед mov AH, attr ; атрибут в AH next: lodsb ; загрузим в AL очередной символ stosw ; выгрузим символ = атрибут из AX в ; видеобуфер loop next ; повторять str_len раз ;Данные str DB ’Пример вывода в видеобуфер’ str_len=$-str attr DB 1Eh ; атрибут всех символов строк Программы с несколькими сегментами команд Рассмотрим программы с расширением ЕХЕ. Любая программа, загружаемая в память, включает три компонента: окружение ENVIRONMENT префикс программы PSP собственно программу, в случае ЕХЕ может состоять из нескольких сегментов. CS,SS,IP и SP инициализируются заголовками из ЕХЕ-файла. Поскольку окружение и сама программа ( включая PSP) рассматриваются DOS , как отдельные блоки памяти, и та, и другая структура предваряются блоками управления памяти МСВ, размером 16 байт. С помощью этих блоков DOS ведёт учёт свободной и занятой памяти. MCB DS:[2Сh], ES:[2Ch] Окружение MCB PSP программа DS,ES CS СОМ программы В этом случае единственный сегмент содержит все компоненты программы. PSP коды команд данные стек В терминах языков высокого уровня это соответствует минимальной или крошечной модели памяти. Преимущество .СОМ прогр. перед ЕХЕкомпакность. Как правило резидентная программа пишется в формате .СОМ. В терминах языков высокого уровня это соответствует минимальной или крошечной модели памяти PSP Программ ас данными стек IP = 0100h SP = 0FFFEh Формат MCB блока смещение длина Содержимое 1 Тип ‘M’ (2Dh) – за этим блоком есть еще блоки MCB Тип ‘Z’ (5Ah) – данный блок последний 1 2 Владелец (сегм. Адрес) 3 2 Размер (число параграфов в памяти) 5 11 Зарезервировано Пример программы с двумя сегментами команд text1 segment ‘code’ assume CS:text1, DS:data main proc mov AX,data mov DS,AX . . call far ptr subr1 . . call far ptr subr2 . . main endp text1 ends text2 segment ‘code’ assume CS:text2, DS:data subr1 proc far . . subr1 endp ; subr2 proc far . . subr2 endp text2 ends data segment … DB … DW . . data ends stack segment stack ‘stack’ DW 128 dup(0) stack ends end main Модели памяти В терминах языков высокого уровня • COM - программа соответствует минимальной или крошечной модели памяти • Если команда помещается в один сегмент команд и данные в одном сегменте данных, то такая .ЕХЕ программа принадлежит к малой модели памяти. • Если требуется увеличить объём команд, то необходимо организовать несколько сегментов команд. Программа с несколькими сегментами команд и одним сегментом данных относится к средней модели памяти. В программе, содержащей несколько сегментов команд, должны быть команды либо перехода из одного сегмента в другой, либо вызов процедуры из другого сегмента. Любое обращение к другому сегменту команд носит название межсегментного или дальнего. Сегмент команд с главной процедурой получил название text1. Процедуры subr1 и subr2 объявлены с описанием far, а её вызовы в главной процедуре сопровождаются описаниями far ptr (far pointerдальний указатель). Вызов не call, а call far ptr. Смещение код команды адрес проц. subr1 000A 9A 0009 4451 call far ptr subr1 1)CS=444D->в стек 2)IP=000F->в стек код операции дальнего 3)4451-> в CS вызова 4)0009-> в IP ret- работает в зависимости от того, как объявлена процедура ret-в дальней проц. снимает со стека два слова. ret-в ближней процедуре снимает со стека одно слово. Т.о. ближние процедуры следует вызывать только из того же сегмента командой ближнего вызова call, в то время, как процедуры, объявленные, как дальние следует вызывать только с помощью команды дальнего вызова call far ptr. Лишь в этом случае завершающие эти процедуры команды ret будут работать правильно. Передача параметров из С программы в функцию на Ассемблере i = 25; J =4; Test (i, j, 1); _Test _Test .MODEL small .CODE PUBLIC _Test Proc push BP mov BP, mov AX, add AX, sub AX, pop BP ret ENDP END SP [BP+4] [BP+6] [BP+8] SP  Return Address SP+2 25 (i) SP+4 4 (j) SP+6 1 Интерфейс с программами на С extern caps(char); main() { char c; for(c='a'; c <= 'z'; c++) caps (c); } func segment public caps caps proc near push BP mov BP, SP mov DL, [BP]+4 sub DL, 32 push DX mov AH, 2 int 21h pop AX pop BP ret 2 caps endp func ends end
«Программная модель МП» 👇
Готовые курсовые работы и рефераты
Купить от 250 ₽
Решение задач от ИИ за 2 минуты
Решить задачу
Помощь с рефератом от нейросети
Написать ИИ
Получи помощь с рефератом от ИИ-шки
ИИ ответит за 2 минуты

Тебе могут подойти лекции

Автор(ы) Гузик В. Ф., Каляев В. А., Костюк А. И.
Смотреть все 588 лекций
Все самое важное и интересное в Telegram

Все сервисы Справочника в твоем телефоне! Просто напиши Боту, что ты ищешь и он быстро найдет нужную статью, лекцию или пособие для тебя!

Перейти в Telegram Bot