
lectures arch+asm.ppt
- Количество слайдов: 180
Архитектура и основы ассемблера Н. Кащеев НИИТ
Обзор курса q Цель курса: Курс дает знания в следующих областях § Архитектура процессора § Архитектура микропроцессорной системы § Основы языка ассемблер § Представление о связи между программированием на языке С и на языке ассемблер q Связь с другими курсами: Курс дает необходимую базу для изучения курсов: § UNIX § Программирование на языке С
Evolution of Computers q First generation (1939 -1954) - vacuum tube q Second generation (1954 -1959) - transistor q Third generation (1959 -1971) - IC q Fourth generation (1971 -present) - microprocessor Http: //history. acusd. edu/gen/recording/computer 1. html
Evolution of Computers q First generation (1939 -1954) - vacuum tube IBM 650, 1954 Http: //history. acusd. edu/gen/recording/computer 1. html http: //www. cs. virginia. edu/brochure/museum. html http: //www. columbia. edu/acis/history/650. html
Evolution of Computers q Second generation (1954 -1959) - transistor Manchester University Experimental Transistor Computer Http: //history. acusd. edu/gen/recording/computer 1. html http: //www. computer 50. org/kgill/transistor/trans. html
Evolution of Computers q Third generation (1959 -1971) - IC PDP-8, Digital Equipment Corporation ¾ Thanks to the use of ICs, the DEC PDP-8 is the least expensive general purpose small computer in 1960 s Http: //history. acusd. edu/gen/recording/computer 1. html http: //www. piercefuller. com/collect/pdp 8. html
Evolution of Computers q Fourth generation (1971 -present) - microprocessor ¾ In 1971, Intel developed 4 -bit 4004 chip for calculator applications. ROM/RAM buffer Timing Reset Control logic Program counter Instruction decoder ALU Reg. I/O Refresh logic http: //www. intel. com System bus Block diagram of Intel 4004 chip layout A good review article: The History of The Microprocessor, Bell Labs Technical Journal, Autumn, 1997
Evolution of Intel Microprocessors Minimum transistor sizes (µm) Number of transistors P III Pentium 80386 8088 80486 P 4 8080 P II 80286 8088 8080 80386 Pentium P III P 4 80486 80286 Clock frequencies (MHz) MIPS P 4 P III Pentium P III 80386 8088 8080 80386 80486 80286 8080 8088 80286 80486 P II P 4
Описания (модели) МП library IEEE; use ieee. std_logic_1164. all; use ieee. numeric_std. all; entity Mux 8 is port (In. Bus : in STD_LOGIC_VECTOR(7 downto 0); Sel : in STD_LOGIC_VECTOR(2 downto 0); Out. Bit : out STD_LOGIC); end Mux 8; architecture Synthesis_1 of Mux 8 is begin process (In. Bus, Sel) begin Out. Bit <= In. Bus(TO_INTEGER (UNSIGNED(Sel))); end process ; end Synthesis_1;
Программная модель МП Microprocessor Bus Control unit Datapath ALU Reg. Memory Output units Input units
What are microprocessors? q 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 q Power. PC (IBM, Motorola) q Athlon, Dulon, Hammer (AMD) q Crusoe (Transmeta) q SPARC, Ultra. SPARC (Sun Microsystems) q TI’s TMS DSP chips (Texas Instruments) q Star. Core (Motorola, Agere) q ARM cores (Advanced RISC Machines) q MIPS cores (MIPS Technologies) q
Applications of Microprocessor-Based Systems q 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 q 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 q 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 q Hardware architecture of microprocessor-based systems ¾ Microprocessor architecture ¾ Memory organization ¾ I/O units of microprocessor-based systems ¾ How to put them together q Programming of microprocessor-based systems ¾ Intel 80 x 86 instruction set ¾ Microprocessor Interrupt services ¾ Assembly language programming
Регистры общего назначения аккумулятор базовый регистр счетчик регистр данных
индекс источника индекс приемника указатель базы указатель стека
Сегментные регистры CS сегмент кода DS сегмент данных ES дополнительный сегмент SS сегмент стека 16 разр IP FLAGH указатель команд FLAGL регистр флагов
регистр флагов
Сегментация памяти Память 00000 00010 + FFFF 1000 F 00010 00020 1 сегмент 2 сегмент 3 сегмент 1000 F 10010
Формат кодирования команд ассемблера [метка] [префикс] команда [операнд(ы)] ; [комментарий] Метка (если имеется), команда и операнд (если имеется) pазделяются по крайней мере одним пробелом или символом табуляции. Максимальная длина строки - 132 символа Метка Команда Операнд count db 1 mov ax, 0 ; Имя, команда, один операнд ; Команда, два операнда
Метки Метка в языке ассемблера может содержать следующие символы: Буквы: Цифры: Спецсимволы: знак вопроса точка знак подчеркивание доллар от a до z и от a до z от 0 до 9 (? ) (только первый символ) (@) (_) ($)
Метки - ограничения n n n Первым символом в метке должна быть буква или спецсимвол. Ассемблер не делает различия между заглавными и строчными буквами. Максимальная длина метки - 31 символ. Примеры меток: count, page 25, $e 10, . cursor Рекомендуется использовать описательные и смысловые метки. Имена регистров, например, AX, DI или AL и т. д. являются зарезервированными и используются только для указания соответствующих регистров.
Функции DOS Код функции в рег-р AH n Заполнение других РОН в соответствии с описанием функции n Вызов DOS int 21 h n Инструкция int - interrupt – программное прерывание n
Вывод на экран символа 2 h AH – номер функции 41 h DL – код символа INT 21 H – вызов функции DOS mov INT AH, DL, 21 H 20 H 02 h ; загружаем в AH число 02 h 2 Ah ; загружаем в DL число 2 Ah ; печать * на экране ; exit
Первая программа code_seg segment assume cs: code_seg, ds: code_seg org 100 h start: mov AH, 2 h mov DL, 2 Ah ; в DL ASCII код int 21 h int 20 h ; выход из программы code_seg ends end start
Листинг трансляции Файл PRIM 1. LST Turbo Assembler Version 3. 1 PRIM 1. ASM 1 0000 2 3 4 0100 5 0100 B 4 02 6 0102 B 2 2 A 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 100 h start: mov AH, 2 h mov DL, 2 Ah int 21 h int 20 h code_seg ends end start
Вывод на экран строки символов Функция 02 h – Выводит 1 символ n Функция 09 Н – печатает целую строку, пока не встретит символ ‘$’ n mov lea Int 21 H AH, DX, 09 mes ; 09 h≡ 9 H ≡ 9 ≡ 11 O ≡ 1001 B ; адрес сообщения
Пример 2 code_seg segment assume cs: code_seg, ds: code_seg, ss: code_seg org 100 h start: jmp begin mes DB 13, 10, ’Привет', 13, 10, '$' begin: mov AH, 9 h lea DX, mes int 21 h int 20 h code_seg ends end start
Листинг трансляции (пример 2) Turbo Assembler Version 3. 1 PRIM 2. ASM 1 0000 2 cs: code_seg, ds: code_seg, ss: code_seg 3 4 0100 5 0100 EB 0 C 90 6 0103 0 D 0 A AF E 0 A 8 A 2 A 5+ 7 E 2 0 D 0 A 24 8 010 E 9 010 E B 4 09 10 0110 BA 0103 r 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 100 h start: jmp begin mes DB 13, 10, 'привет', 13, 10, '$' begin: mov AH, 9 h lea DX, mes int 21 h int 20 h code_seg ends end start
Вывод на экран шестнадцатеричной цифры Сhar ASCII Code (HEX) / 2 F 0 30 1 31 2 32 3 33 4 34 5 35 6 36 7 37 8 38 9 39 : 3 A ; 3 B mov цифры 0 int 21 h + 30 h mov AH, 02 h mov DL, 39 h ; вывод цифры 9 int 21 h 3 C = 3 D 3 E ? 3 F @ 40 AH, 02 h DL, 30 h ; вывод 7 Вместо хранения таблицы ASCII в программе, код цифры можно сформировать сложением цифры и константы 30 h
Продолжение ASCII таблицы @ A 41 B 42 C 43 D 44 E 45 F 46 G 47 mov AH, 02 h mov DL, 41 h ; вывод цифры (буквы) A int 21 h 40 +037 H РОН = РОН+ 030 h if РОН 03 Ah then РОН=РОН+07 h Print РОН Пример: 0 A+30 h=3 Аh 3 Ah+07 h=41 h На ассемблере: mov AH, 02 h mov DL, BL add DL, 030 h cmp DL, 3 Ah jl print_letter add DL, 07 h print_letter: int 21 h
Вывод на экран содержимого младшей тетрады регистра BL code_seg segment assume CS: code_seg, DS: code_seg, SS: code_seg org 100 h start: mov AH, 9 h ; функция DOS для вывода стр. символов ( $ ; ограничитель стр. ) lea DX, mes ; ≡ mov DX, offset mes int 21 h ; print string ; mov BL, 0 Fh ; загружаем в BL известное число, чтобы ; проверить правильность вывода mov AH, 02 h mov DL, BL add DL, 30 h cmp DL, 3 Ah jl print add DL, 07 h print: int 21 H int 20 h mes DB 13, 10, 'я печатаю HEX содержимое мл. тетрады регистра BL', 13, 10, '$‘ code_seg ends end start
Процедура Это список инструкций, который можно вызвать из различных мест программы. Аналог функции в С и подпрограммы. Процедуру можно вызвать с помощью CALL имя процедуры выход из процедуры ret. Адрес возврата запоминается в стеке. Call Primer_proc … … Primer_proc: proc near инструкция. . . ret тело процедуры
Вывод на экран содержимого регистра BL mov rcr call mov call int ; print_hex: mov and add cmp jl add print: ret DL, BL DL, 4 print_hex DL, BL print_hex 20 h proc near AH, 02 h DL, 0 Fh DL, 030 h DL, 03 Ah print DL, 07 h int 21 h ; сдвиг вправо на 4 бита
Команды циклического сдвига CF 0 0 0 1 0 0 0 0 1 0 1 1 0 0 0 1 rcr DL, 4 результат rcl DL, результат 4
Поразрядное логическое AND 0 0 1 0 1 0 0 0 1 1 1 0 0 0 1 0 DL, 1 0 and результат 0 Fh
Cформировать байт из 2 -х шестнадцатиричных цифр code_seg segment assume cs: code_seg, ds: code_seg, ss: code_seg org 100 h start: jmp write_string mes: DB 13, 10, 'Я формирую байт из 2 х вводимых HEX цифр', 13, 10, '$' write_string proc near mov AH, 9 h ; функция DOS для вывода строки символов ; $ - ограничитель строки lea DX, mes int 21 h ; print string write_string endp ; main proc near ; Ввод шестнадцатеричных цифр call inp_hex mov DL, AL rol DL, 4 call inp_hex add DL, AL int 20 h main endp
inp_hex proc push cycle: mov int cmp jb cmp ja mov int sub pop ret near DX AH, 21 h AL, beep AL, cont AH, DL, 21 h AL, DX 08 h ; function - input char without echo 030 h ; if < beep (unsigned) 046 h ; if > beep (unsigned) 039 h 02 h AL ; print char 030 h ; code ASCII-030 h--> hex digit
beep: mov int jmp AH, DL, 21 h short 02 h 07 h cycle cont: cmp AL, jb beep mov AH, mov DL, int 21 h sub AL, pop DX ret inp_hex endp code_seg ends end start 041 h 02 h AL 037 h ; code of beep
Домашнее задание Вывод содержимого регистра BX n Ввод 4 -х шестнадцатиричных цифр и формирование из них содержимого регистра BX n
Вывод на экран двоичного числа code_seg segment assume cs: code_seg, ds: code_seg, ss: code_seg org 100 h start: jmp begin mes: DB 13, 10, 'я печатаю двоичное содержимое регистра BX', 13, 10, '$' begin: mov AH, 9 h ; функция DOS для вывода строки символов ; $ - ограничитель строки lea DX, mes int 21 h ; print string ; mov BX, 0 A 3 C 5 h mov CX, 16 mov AH, 02 ; функция- печать символа из DL cycle: rcl BX, 1 ; цикл. сдвиг BX на 1 разряд влево mov DL, 00 ; сложение с учетом значения флага переноса CF adc DL, 30 h int 21 H приемник=приемник+источник+CF loop cycle int 20 h code_seg ends end start Если шестнадцатеричное число начинается с буквы, то в программе такое число должно записываться с ведущим 0 (для того, чтобы отличить от меток или от обозначения регистров), Например, число А – 0 Ah, а не Ah – чтобы не спутать с регистром AH.
Работа с файлами В DOS доступны следующие функции работы с файлами: n 39 h – создать каталог файлов (аналогично функции MKDIR DOS) n 3 Аh – удалить каталог n 3 Вh – сменить текущий каталог n 3 Сh – создать файл (CREATE) n 3 Dh – открыть файл (OPEN) n 3 Eh – закрытие файла (CLOSE) n 3 Fh – читать данные из файла или устройства (READ) n 40 h – записать данные в файл или на устройство (WRITE) n 41 h – удалить файл (DELETE) n 42 h – переместить указатель текущей позиции в файле n 43 h – получить/установить аттрибуты файла n 56 h – переименовать файл n 57 h – получить/установить дату и время последнего изменения файла n 5 Ah – создать временный файл n 5 Bh – создать новый файл (В отличие от 3 Сh, если файл уже существует, то 5 Bh сообщает об ошибке). n 5 Сh – блокировать/разблокировать доступ к файлу.
Работа с каталогом n 39 h – создать каталог файлов (аналогично функции MKDIR DOS) перед использованием DS: DX – адрес ASCIIZ – строки –имя пути для нового каталога. Ошибки в АХ: 3 - путь не найден 5 – ошибка в доступе n 3 Аh – удалить каталог DS: DX – адрес ASCIIZ – строки –имя пути для нового каталога. Ошибки в АХ те же n 3 Вh – сменить текущий каталог DS: DX – адрес ASCIIZ – строки –имя пути для нового каталога Ошибки в АХ: 3 - путь не найден
АSCIIZ-строка n Функции DOS, работающие с файлами, требуют задания имени и пути к файлу в виде ASCIIZ строки. ASCIIZ строка состоит из обычных ASCII символов, за которыми следует нулевой байт. Типичная строка выглядит наподобие: n C: DIRECTORY 1DIRECTORY 2FILENAME. EXT n В качестве разделителя может быть как прямая, так и обратная косая черта. (имя дисковода может быть опущено)
Функция - создать файл n n 3 Сh – создать файл (CREATE) открывает существующий или создает новый файл. DS: DX – адрес ASCIIZ строки. СХ – атрибут файла АХ – возвращается логический номер файла. Логический номер файла или дескриптор – это 16 -битовое число, используемое DOS как указатель на систему таблиц. Логический номер освобождается после закрытия файла и может быть использован повторно.
Особенности функции - CREATE n n После выполнения всех необходимых действий по созданию файла, функция 3 Сh возвращает в регистре АХ дескриптор созданного файла, которым мы можем в дальнейшем пользоваться для записи в файл или чтения из него. Если файл с заданным именем уже существовал, функция 3 Сh фактичеки уничтожит имеющийся файл и создаст новый с тем же именем.
Атрибут файла В СХ, а точнее, в СL задается – атрибут файла n 0 – отсутствие атрибутов n 1 – только чтение n 2 – скрытый файл n 4 – системный n 8 – метка тома n 16 = 10 h – подкаталог n 32 = 20 h – архив – этот разряд сброшен для всех файлов, которые изменялись последнего копирования
Существует пять стандартных логических номеров 0 - 4, которые автоматически предоставляются любой программе Логический номер Использование Устройство по умолчанию 0 Стандартный ввод (клавиатура) CON: 1 Стандартный вывод (экран) CON: 2 Стандартное устройство вывода при ошибке CON: 3 Стандартное вспомогательное устройство AUX: 4 Стандартное устройство печати PRN: Остальные номера с большими логическими номерами DOS предоставляет по требованию
Проверка ошибок n Так как АХ используется для возврата как логического номера, так и кода ошибки, то в качестве признака ошибки используеся флаг CF (флаг переноса) n Возможны коды возврата: 3 – путь не найден 4 – нет свободного логического номера 5 – отказ в доступе – либо в каталоге нет места для новой записи, либо уже существующий файл защищен от записи и не может быть открыт для вывода данных.
Файловая функция mov AH, 3 Ch ; AH 3 Ch, 3 D, …. …. …. int 21 h нет Произошла ошибка, в AX – код ошибки CF=0 ? да Ошибок нет – в AX - дескриптор
Анализ системных ошибок MOV AH, Function ; Номер функции ; Заполнение регистров параметрами, ; необходимыми для ; выполнения данной функции INT 21 h JC Error ; флаг СF установлен ; Нет, нормальное продолжение программы ………… Error: … ; Да, анализ ошибок в АХ CMP AX, 1 JE Error 1 CMP AX, 2 JE Error 2 …. .
Функция 3 Dh - открыть файл (OPEN) DS: DX – адрес строки, содержащей путь и имя файла AL - код режима открытия Рассмотрим только разряды 0 2. 2 1 0 0 0 1 0 Только чтение Только запись Чтение/запись Бит 7 – бит наследования Биты 4 -6 – режимы совместного использования. Коды возврата в АХ: 2 – файл не найден 3 – путь не найден 4 – нет свободного логического номера файла 5 – отказ в доступе 12 – недопустимый код доступа
3 Eh – закрыть файл (CLOSE) Логический номер в ВХ Номер функции 3 Eh AH int 21 h Код ошибки: 6 – ошибочный логический номер
3 Fh – читать данные из файла (READ) Логический номер Число байт Адрес буфера ВХ СХ DS: DX В АХ возвращается число действительно считанных байтов Если в АХ 0, то программа пыталась считать данные за концом файла Код ошибки: 5 – отказ в доступе 6 – ошибочный логический номер
Процесс чтения из файла память устройство Указатель текущей позиции в файле файл Область программы DS: DX Буфер ввода Размер число байт в CX Дескриптор в BX
40 h – записать данные в файл (WRITE) n n n n Логический номер ВХ. Число байт СХ Адрес выводимых данных DS: DX В АХ возвращается число действительно выведенных байтов. Проверка состоит их 2 х шагов СF=1? AX = CX? Если АХ<СХ – на диске не хватило места.
41 h – удалить файл (DELETE) DS: DX – адрес строки, определяющей имя файла. n Заполнители ? и * в имени файла использовать нельзя. n
42 h – переместить указатель текущей позиции в файле n n n n n Логический номер – ВХ. Новое положение указателя задается путем загрузки в регистр AL исходного положения указателя, а в пару регистров СХ: DX – число байтов, на которое необходимо переместить указатель. Загружаемое в пару регистров СХ: DX смещение в байтах – это 32 -битовое число без знака. В СХ – старшая часть, в DX – младшая. Если смещение меньше 65535, то СХ = 0. Исходное положение в АL задается с помощью так называемого кода метода: АL = 0 – смещение берется от начала файла и указатель изменяется на СХ: DX от этой точки АL = 1 – смещение берется от текущей позиции АL = 2 – смещение берется от конца файла. В последнем случае в паре регистров СХ: DX обычно ноль, чтобы определить текущий размер файла. Если задать смещение 0 и запросить метод 0 – то возврат в начало файла. Коды ошибок: 1 – ошибочный номер функции 6 – ошибочный логический номер
Пример 1 ; создание файла MOV AH, 3 Ch ; Функция CREATE MOV CX, 0 ; Без атрибутов MOV DX, OFFSET Filename ; Адрес имени Файла INT 21 h ; Вызов DOS Mov Handler, AX ; сохранить дескриптор ; запись строки в файл MOV AH, 40 h ; Функция записи MOV BX, Handler ; Дескриптор MOV CX, Buf. Len ; Число записываемых байтов MOV DX, OFFSET Buf ; Адрес буфера INT 21 h ; закрытие файла MOV AH, 3 Eh ; MOV BX, Handler INT 21 h ; завершение программы MOV AX, 4 C 00 h ; Функция завершения INT 21 h ; данные Buf DB ‘ 0123456789’ ; Данные, записываемые в файл Buf. Len EQU $ - Buf ; Длина данных. $ - текущее значение счетчика Handler DW ? ; Ячейка для дескриптора Filename DB ‘D: testmyfile. 001’, 0 ; ASCIIZ строка спецификации файла
Пример 2 ; Открыть файл MOV AH, 3 Dh ; функция OPEN MOV AL, 2 ; Доступ для чтения/записи MOV DX, OFFSET Filename ; Адрес имени файла INT 21 h MOV Handler, AX ; Сохранение дескриптора ; Пытаемся прочитать 65535 байт MOV AH, 3 Fh ; Функция READ MOV BX, Handler ; Дескриптор MOV CX, 65535 ; Сколько читать MOV DX, OFFSET Buf. In ; Сюда читать INT 21 h MOV CX, AX ; сколько реально прочитано ; Вывод прочитанного на экран MOV AH, 40 h ; функция WRITE MOV BX, 1 ; Дескриптор стандартного вывода MOV DX, OFFSET Buf. In ; отсюда выводить (СХ байт) Int 21 h ; Данные Buf. In DB 80 dup (‘ ‘) ; буфер ввода Handler DW ? Filename DB ‘D: testmyf. 001’, 0 ; спецификация файла
Функции для работы с файлами 43 h – получить, установить аттрибуты файла 56 h – переименовать файл 57 h – получить/установить дату и время последнего изменения файла в DOS 3. 00 5 Ah – создать временный файл CX - атрибут DS: DX – имя пути, должно заканчиваться ‘’ Строка должна иметь длину на 12 байт больше длины имени пути, чтобы DOS могла бы дополнить уникальным именем файла. 5 Bh – создать новый файл. В отличие от 3 Сh, если файл уже существует, то 5 Bh сообщает об ошибке. 5 Сh – блокировать/разблокировать доступ к файлу.
Программный загрузчик n Ц е л ь: Понять как DOS загружает программу в память и управляет ее исполнением
DOS состоит из четырех основных программ 1 Блок начальной загрузки находится на первом секторе нулевой дорожки дискеты DOS, а также на любом диске, форматированном командой FORMAT/S. 2 Программа IBMBIO. COM обеспечивает интерфейс низкого уровня с программами BIOS в ROM. При инициализации программа IBMBIO. COM определяет состояние всех устройств и оборудования, а затем загружает программу COMMAND. COM 3 Программа IBMDOS. COM обеспечивает интерфейс высокого уровня с программами. Эта программа управляет оглавлениями и файлами на диске, блокированием и деблокированием дисковых записей, функциями int 21 h, а также содержит ряд других сервисных функций. 4 Программа COMMAND. COM выполняет различные команды DOS, такие как DIR или CHKDSK, а также выполняет com, exe и batпрограммы. Она состоит из трех частей: небольшая резидентная часть, часть инициализации и транзитная часть. Программа COMMAND. COM отвечает за загрузку выполняемых программ с диска в память.
Распределение адресного пространства в DOS Физический адрес Содержимое Объем (Кб) 00000 h таблица векторов прерываний 640 00400 h Область связи с ROM (ПЗУ) 00500 h Область связи с DOS 00600 h IBMBIO. COM xxxx 0 h IBMDOS. COM Буфер каталога, Дисковый буфер, Таблица параметров дисковода или таблица распределения файлов (FAT, по одной для каждого дисковода) xxxx 0 h Резидентная часть COMMAND. COM xxxx 0 h Внешние команды или утилиты (com или exe-файлы) xxxx 0 h Пользовательский стек для com-файлов (256 байт) xxxx 0 h Транзитная часть COMMAND. COM, записывается в самые старшие адреса памяти. A 0000 h Графический видеобуфер 64 B 0000 h Свободные адреса 32 B 8000 h Текстовый видеобуфер 32 C 0000 h ПЗУ-расширения BIOS 64 D 0000 h Свободные адреса 64 E 0000 h ПЗУ BIOS 128
Командный процессор COMMAND. COM Система загружает три части программы COMMAND. COM в память во время сеанса работы постоянно или временно. Ниже описано назначение каждой из трех частей COMMAND. COM: 1. Резидентная часть непосредственно следует за программой ibmdos. com. Резидентная часть обрабатывает все ошибки дисковых операций ввода-вывода и управляет следующими прерываниями: int 22 h Адрес программы обработки завершения задачи. int 23 h Адрес программы реакции на ctrl/break. int 24 h Адрес программы реакции на ошибки дисковых операций чтения/записи или сбойный участок памяти в таблице распределения файлов (FAT). int 27 h Завершение работы, после которого программа остается резидентной.
Часть инициализации COMMAND. COM 2. Часть инициализации непосредственно следует за резидентной частью и содержит средства поддержки autoexec-файлов. В начале работы системы данная часть первой получает управление. Она определяет сегментный адрес, куда система должна загружать программы для выполнения. Ни одна из этих программ инициализации не потребуется больше во время сеанса работы. Поэтому первая же команда вводимая с клавиатуры и вызывающая загрузку некоторой программы с диска перекрывают часть инициализации в памяти.
3. Транзитная часть COMMAND. COM n. Транзитная часть загружается в самые старшие адреса памяти. n. Выводит на экран приглашение C>, вводит и выполняет запросы. n. Содержит настраивающий загрузчик и предназначена для загрузки COM- или EXE-файлов с диска в память для выполнения. n. Если поступил запрос на выполнение какой-либо программы, то транзитная часть строит префикс программного сегмента (PSP) непосредственно вслед за резидентной частью COMMAND. COM. n. Затем она загружает запрошенную программу с диска в память по смещению 100 h от начала программного сегмента, устанавливает адреса выхода и передает управление в загруженную программу.
Ниже приведена данная последовательность: IBMBIO. COM IBMDOS. COMMAND. COM (резидент) Префикс программного сегмента Выполняемая программа . . . COMMAND. COM (транзитная часть, может быть перекрыта). Выполнение команды RET или INT 20 H в конце программы приводит к возврату в резидентную часть COMMAND. COM. Если транзитная часть была перекрыта, то резидентная часть перезагружает транзитную часть с диска в память
Образ памяти программы типа. COM После загрузки программы все четыре сегментных регистра указывают на начало единственного сегмента. Указатель стека автоматически инициализируется числом FFFEh. Таким образом программе выделяется 64 Кб адресного пространства, всю нижнюю часть которого занимает стек. CS, DS, ES, SS PSP IP = 0100 h Программа и данные стек SP = FFFEh
ПРЕФИКС СЕГМЕНТА ПРОГРАММЫ (PSP) (program segment prefix) n n PSP – это область размером 100 h (25610), которая содержит информацию, необходимую DOS для обеспечения работы программы. Для СОМ-программы сегментные регистры (CS, DS и ES) указывают на начало PSP, а программа размещается сразу вслед за PSP, то есть со смещением 100 h от начала PSP.
Структура префикса программного сегмента Поле Смещение от начала PSP Размер поля (десятичн) Значение 1 00 h 2 байт Команда INT 20 h 2 02 h 2 байт Размер памяти в параграфах 3 04 h 1 байт Резерв, обычно 0 4 05 h 5 байт Вызов диспетчера функций DOS 5 0 Ah 4 байт Вектор завершения работы (Адрес завершения CS: IP) 6 0 Eh 4 байт Вектор прерывания работы (Адрес выхода Ctrl-Break) 7 12 h 4 байт Вектор ошибки (Адрес выхода по ошибке) 8 16 h 22 байт Используется DOS 9 2 Ch 2 байт Указатель строки связи с окружающей средой 10 2 Eh 34 байт Рабочая область DOS 11 50 h 3 байт Коменды INT 21 h, RETF 12 53 h 2 байт Зарезервировано 13 55 h 7 байт Расширение FCB #1 14 5 Ch 9 б айт FCB #1 15 65 h 7 байт Расширение FCB #2 16 6 Ch 20 байт FCB #2 17 80 h 1 байт Длина параметров 18 81 h 127 байт Параметры 19 80 h 128 байт Область передачи информации
Поле 1 n n Прерывание INT 20 h используется для завершения программы и передачи управления DOS. Прерывание INT 20 h эквивалентно AH=0 (функции 0) INT 21 h. INT 20 h не закрывает все открытые этой программой файлы. Более совершенная функция выхода из программы 4 Сh - завершает работу программы и передает тому, кто ее вызвал, код возврата. Если программа была вызвана как подпрограмма, то вызвавшая ее программа может получить код возврата с помощью функции 41 h. Если программа вызывалась командой DOS, то код возврата может быть проверен в командном файле с помощью команды ERRORLEVEL. Код возврата возвращается в AL. При выполнении этой функции DOS автоматически закрывает все файлы, открытые с помощью 3 Dh и, возможно, 3 Сh. Итак, команда INT 20 h находится в начале PSP. Таким образом, можно выйти из программы, просто передав управление на эту ячейку (при условии, что CS указывает на PSP). Размещение в начале PSP команды INT 20 h может быть объяснено тем, что если LINK обнаруживает в программе неудовлетворенную внешнюю ссылку, то он присваивает ее адресу смещения 0. при передаче управления на эту ссылку выполнится команда, находящаяся в начале PSP, то есть INT 20 h, - что вызовет завершение программы.
Поле 2 n n сколько памяти доступно – содержит номер последнего блока памяти, доступной DOS. Умножив это число на 16, получим общий объем памяти в байтах. То же самое значение, что и в поле 2, возвращает команда CHKDSK DOS. Если программе необходима вся доступная память, то она должна использовать это поле PSP для определения того, сколько памяти она может использовать. Программа также может получать и возвращать память с помощью вызова функции 4 Аh.
Поле 4 n n Это команда вызова с атрибутом дистанции FAR диспетчера функций DOS. Следовательно, эта команда содержит полный адрес диспетчера. Этот полный адрес не только указывает на диспетчера, но при этом его смещение указывает, сколько памяти в сегменте команд мы можем использовать (до FFF 0, то есть на 16 байт меньше, чем 64 КБайт). Это смещение расположено в PSP со смещением 6, сразу за кодом команды, имеющим смещение 5. Это поле, в отличие от предыдущего, должно работать с большинством многооконных и мультипрограммных систем. Если DOS может предоставить более 64 Кбайт, то определить, на сколько больше, мы можем по полю 2.
Поле 5, 6 и 7 n Это полные адреса, для трех прерываний по завершению работы, по Ctrl-Break (Ctrl-C) и по ошибке. Если мы хотим использовать свои программы для обработки этих ситуаций, то должны временно изменить эти слова. В конце работы вектора должны быть восстановлены
Поле 9 n n Полный адрес набора строк описания окружающей среды. это набор ASCIIZ строк. каждая строка имеет форму ИМЯ = значение Обычно эта среда содержит по крайней мере имя СОМSPEC (используемое DOS для поиска на диске файла COMMAND. COM).
Поле 11 n n Содержит команды INT 21 h и команду возврата управления вызвавшей программе RETF ( RET с дальним аттрибутом дистанции FAR). Таким образом, вместо INT 21 h мы можем косвенно через смещение в PSP вызвать эту команду.
Поле 13, 14, 15 и 16 n n Содержит команды INT 21 h и команду возврата управления вызвавшей программе RETF ( RET с дальним аттрибутом дистанции FAR). Таким образом, вместо INT 21 h мы можем косвенно через смещение в PSP вызвать эту команду.
Поле 17, 18 n n Обеспечивают нашим программам доступ к параметрам командной строки. Поле 17 содержит полную длину строки параметров (которая может быть от 0 до 127), а поле 18 – ее содержимое. Передаваемая строка не содержит имя вызванной программы. Строка начинается с символа, следующего в команде вызова сразу за именем программы; обычно это пробел. Разделители, пробелы и запятые не отбрасываются и не снимаются. Любые параметры переадресации ввода/вывода, такие как < ввод > вывод изымаются DOS и строка реконструируется таким образом, как будто этих элементов не было вообще. В результате этих двух операций программа не может узнать о переадресации стандартного ввода-вывода и не может узнать свое собственное имя.
Поле 19 n Это область, которая по умолчанию используется DOS для обмена данными с диском (DTA – Disk Transfer Area). Это буфер длиной 128 байт, имеющий смещение 80 h. Используется всегда, когда мы пользуемся служебной процедурой DOS для обмена с диском, не задавая в качестве буфера свою собственную область.
Команды обработки строк Для обработки строковых данных ассемблер имеет пять команд обработки строк: n movs - n lods - n n stos - cmps - n 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 обеспечивает повторение команды несколько раз. n Префикс кодируется непосредственно перед цепочечной командой, например, rep movsb. n Для использования префикса rep необходимо установить начальное значение в регистре cx. n При выполнении цепочечной команды с префиксом rep происходит уменьшение на 1 значения в регистре cx до нуля. Таким образом, можно обрабатывать строки любой длины. Флаг направления определяет направление повторяющейся операции: n для направления слева направо необходимо с помощью команды cld установить флаг df в 0; n для направления справа налево необходимо с помощью команды std установить флаг df в 1.
Пример: выполняется пересылка 20 байт из string 1 в string 2 Предположим, что оба регистра ds и es инициализированы адресом сегмента данных string 1 string 2 db 20 dup('*') db 20 dup(' '). . . cld mov cx, 20 lea di, string 2 lea si, string 1 rep movsb ; Сброс флага df ; Счетчик на 20 байт ; Адрес области "куда « ; Адрес области "откуда" ; Переслать данные
При выполнении команд cmps и scas возможна установка флагов состояния, так чтобы операция могла прекратиться сразу после обнаружения необходимого условия. Ниже приведены модификации префикса rep для этих целей: nrep - повторять операцию, пока cx не равно 0; nrepz или repe - повторять операцию, пока флаг zf показывает "равно или ноль". Прекратить операцию при флаге zf, указывающему на не равно или не ноль или при cx равном 0; nrepne или repnz - повторять операцию, пока флаг zf показывает "не равно или не ноль". Прекратить операцию при флаге zf, указывающему на "равно или нуль" или при cx равным 0.
Пример проверки командной строки mov repe cmp je xor cld mov mov scasb repe dec mov cmpsb CL, ES: 80 h ; Длина хвоста в PSP CL, 0 ; Длина хвоста=0? install_without_arg ; Да, прогр. запущена без пар. CH, CH ; CX=CL= длина хвоста ; DF=0 - флаг направления вперед DI, 81 h ; 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
Домашнее задание n Написать программу, распечатывающую содержимое PSP
ПРЕРЫВАНИЯ Прерывание (interrupt) – это аппаратная функция, вызывающая приостановку операций CPU, запоминание его состояния и выполнение специальной программы, которая называется программой обработки прерывания (interrupt service routine - ISR) или обработчиком прерывания (interrupt handler). Существует три класса прерываний: n внутренние n внешние (аппаратные) n программные Внутренние прерывания инициируются состоянием самого процессора (например, деление на ноль) Внешние – сигналом, подаваемым в CPU другими компонентами вычислительной системы (например, при любом нажатии на клавишу). Программные прерывания – специальной командой INT.
Независимо от источника прерывания, последовательность действий, выполняемых CPU по обслуживанию прерывания всегда одинаковая, как для аппаратного, так и для программного прерывания. Микропроцессоры семейства 8086 способны обрабатывать 256 типов прерываний. Каждое прерывание имеет номер от 0 до 255.
Начало оперативной памяти от адреса 0000 h до 03 FFh отводится под векторы прерываний. Вектор прерывания – это 2 слова памяти (4 Байта), в которых хранятся адреса программ обработки прерываний (ISR). В старшее слово записывается сегментный адрес ISR, в младшее слово – смещение ISR, то есть относительный адрес точки входа ISR в сегменте. Вектор 0 располагается, начиная с адреса 0, вектор 1 – с адреса 4, вектор 2 – с адреса 8 и т. д. Вектор с номером N занимает, таким образом, байты с N*4 до N*4+3.
Процедура прерывания IP ISR 1 6 CS ISR 1 8 IP ISR 2 A CS ISR 2 Nx 4 CS CS ISR 0 4 IP IP ISR 0 2 CPU 0 IP ISRN Nx 4+2 CS ISRN Flags 3 FC IP ISR 255 3 FE CS ISR 255 400 Old IP New SP Old CS Flags Вектор прерванного процесса Stack Old SP
Программа обработки прерывания Вход по прерыванию, например, по команде Сохранение используемых регистров в стеке int Тело ISR Восстановление регистров из стека iret Восстанавливает из стека 3 регистра IP CS Flags
Изменение содержимого вектора прерывания Рассмотрим как заполнить вектор «вручную» , т. е. без использования функций DOS n Использование функций DOS для изменения содержимого вектора n ¨ Сохранение вектора ¨ Заполнение вектора
Заполнение вектора Вектор можно изменить непосредственно засылая слова по адресу вектора. n При изменении вектора нужно соблюдать определенные меры предосторожности. Например, если мы изменили только одно слово вектора и возникает прерывание по этому вектору, то это приведет к зависанию программы. Для того, чтобы исключить прерывания в процессе изменения вектора, команды изменяющие вектор должны выполняться при запрещенных прерываниях. n Команда CLI запрещает прерывания, все кроме NMI-немаскируемых прерываний. n
Пример заполнения вектора 65 h xor ax, ax mov es, ax cli прерывания mov word ptr es: 65 h*4, ; переслать смещение ; запретить offset new_65 h ; точки входа в ; обработчик mov word ptr es: 65 h*4+2, сегментную часть sti прерывания. . . new_65 h: push. . . pop iret DS ; и ; разрешить
Функции DOS для сохранения/изменения вектора прерывания n Получить вектор прерывания Функция 35 h Применение: 35 h AH Номер вектора AL int 21 h Возврат ES: BX – содержимое вектора (указатель на программу обработчика)
n Изменить вектор прерывания Функция 25 h Применение: 25 h AH Номер вектора AL int 21 h В DS: DX – новое содержимое вектора (указатель на программу обработчика)
Пример изменения вектора прерывания old_09 h. . . DD ? mov int mov mov AX, 3509 h ; получить вектор 21 h ; прерывания 09 h word ptr old_09 h, BX ; ES: BX - вектор word ptr old_09 h+2, ES DX, offset new_09 h ; получить смещение точки ; входа в новый обработчик на DX mov AX, 2509 h ; функция установки прерывания ; изменить вектор 09 h int 21 h ; AL - номер прерыв. ; DS: DX - указатель программы обработки прер. . . . new_09 h: ; точка входа в обработчик
Пример code_seg segment assume cs: code_seg, ds: code_seg, ss: code_seg org 100 h start: jmp begin line db 2 column db 10 sym db 01 h begin: mov AH, 25 h ; ф-я заполнения вектора прер. mov AL, 65 h ; номер вектора mov DX, offset new_65 h ; смещение обработчика int 21 h gogo: int 65 h mov AH, 02 h ; функция позиционирования mov BH, 0 ; видеостраница mov DH, line ; строка mov DL, column ; столбец int 10 h
mov AH, 0 Ah ; ф-я вывода символа без атрибута mov AL, sym ; символ mov BH, 0 ; видеостраница mov CX, 60 ; коэффициент повторения int 10 h inc sym ; следующий символ inc line ; следующая строка mov ah, 08 h ; ф-я выв без эха, чувствительная к Ctrl+C int 21 h jmp gogo new_65 h proc near mov AH, 06 h ; функция задания окна mov AL, 0 ; режим создания (нет прокрутки) mov BH, 1 bh ; атрибут всех символов в окне ; (светло-бирюзовые символы, синий фон) mov CX, 0 ; левый верхний угол 0, 0 mov DH, 24 ; нижняя Y-координата mov DL, 79 ; правая X-координата int 10 h iret new_65 h endp code_seg ends end start
Табличные вызовы подпрограмм Для вызова функции DOS в AH заносится номер функции и с помощью int 21 h вызывается диспетчер DOS. Диспетчер извлекает из AH номер функции и активизирует по этому номеру соответствующую программу из числа функций DOS. Рассмотрим упрощенную имитацию диспетчера DOS. В нашей программе должен быть диспетчер, вызываемый с помощью прерывания и передающий управление подпрограмме с заданным в AH номером. Адрес диспетчера внесем в один из свободных векторов прерывания.
Номер функции пересылается из AH в регистр BX, который в дальнейшем используется в качестве индексного. Сдвиг BX соответствует умножению на 2. Теперь BX - индекс, в таблице адресов addr_tbl, в которой записаны смещения (относительные адреса) подпрограмм в порядке, определяющем их номера. jmp start ; Диспетчер прерывания 65 h new_65 h: push bx push dx mov bl, ah mov bh, 0 shl bx, 1 ; Лог. сдв. влево на один разряд call add_tbl[bx]; pop dx pop bx iret
; Подпрограммы-функции Продолжение программы. . . sub 0: mov ah, 9 lea dx, mes 0 int 21 h ret. . sub 4: mov ah, 9 lea dx, mes 4 int 21 h ret start: mov ax, 2565 h ; ф-ия заполнения вектора ; прер. int 65 h mov dx, offset new_65 h int 21 h
Продолжение программы. . . ; Последовательно вызываем подпрограммы mov ah, 0 int 65 h mov ah, 1 int 65 h. . mov ah, 4 int 65 h mov ax, 4 c 00 h ; exit int 21 h
Продолжение программы. . . ; Таблица адресов и подпрограмм add_tbl dw sub 0 dw sub 1. . dw sub 4 ; Сообщения mes 0 db ‘Отработала подпрограмма 0’, 13, 10, ’$’. . mes 4 db ‘Отработала подпрограмма 4’, 13, 10, ’$’
Резидентные программы TSR (Terminate and Stay Resident) n n n Любая TSR программа содержит один или несколько взаимодействующих друг с другом обработчиков прерываний, которые обеспечивают запуск программы и выполняют служебные функции. После прерывания регистры DS, ES, SS содержат прежние значения (какими они были до прерывания), поэтому внутри обработчика нужно использовать адресацию относительно CS. Чаще всего резидентные программы не полностью заменяют имеющиеся обработчики прерываний, а лишь дополняют их.
Формат TSR программы entry: ; ; ; boot: jmp org boot 100 h Обработчик прерывания (резидентная часть) вызов старого обработчика (с возвратом или без возврата) ; часть инициализации ; изменение вектора прерывания mov dx, offset boot int 27 h end entry
Функция DOS - завершить программу и оставить в памяти n int 27 h - CS - DX - завершить программу и оставить резидентной сегментный адрес PSP смещение первого байта освобождаемой памяти
Вызов старого обработчика n Передача управления без возврата. Передать управление исходному обработчику можно: jmp n Передача управления с возвратом. (Имитация прерывания по старому вектору): pushf call n dword ptr [old_int_vect] Это для iret, которая извлекает из стека три слова Здесь old_int_vect - двойное слово, в котором сохранен исходный вектор прерывания. old_int_vect DD ?
Защита резидентной программы от повторной загрузки n n n Если в резидентной программе нет защиты от повторной загрузки, то при повторном её запуске станет резидентной её вторая копия. И т. д. этот процесс может продолжаться до тех пор, пока не будет исчерпана оперативная память Наиболее распространенным методом защиты резидентной программы от её повторной установки является использование мультиплексного прерывания 2 Fh, специально предназначенного для взаимодействия с резидентными программами
Мультиплексное прерывание 2 Fh Вызов: AH номер мультиплексного процесса (идентифицирует обработчик прерывания) 00 H-7 FH Резерв DOS 80 h-B 7 h доступны B 8 h-8 Fh резерв для сетей C 0 h-FFh доступны для прикладных программ В частности, номера 00 и 01 закреплены за резидентной программой DOS print. com 02 h рез. порция assign 10 h рез порция share Al номер функции Al 00 h - дать статус установки процесса Возвращает: Al статус установки 00 h не установлен - можно устанавливать 01 h не установлен - нельзя устанавливать FFh установлен
Обработка прерывания 2 Fh в резидентной программе n n Для того, чтобы резидентная программа могла отозваться на int 2 Fh, в ней должен иметься обработчик этого прерывания. Через этот обработчик может быть осуществлена не только проверка на повторную инициализацию, но и вообще связь с резидентной программой - смена режима её работы или получения от нее каких-то параметров. Задания действий осуществляются с помощью функции, заданной в AL. Таким образом обработчик должен прежде всего проверить номер процесса в AH и при обнаружении своего номера проанализировать AL и выполнить затребованные действия, после чего с помощью iret передать управление вызвавшей программе. Если обработчик обнаружил в AH - номер чужого процесса, он должен командой jmp передать управление по цепочке тому обработчику, адрес которого был ранее в векторе 2 Fh. В результате вызов int 2 fh из любой программы будет проходить по цепочке через все загруженные программы, пока не достигнет «своей» программы или не вернет управление в вызвавшую программу через обработчик DOS, который, очевидно, всегда будет самым последним в цепочке
Альтернативное мультиплексное прерывание int 2 Dh AH - мультиплексный номер AL - функция 00 h - проверка инсталляции Возврат al=0 -не установлен al=ffh установлен cx-версия dx: di - строка сигнатуры al=02 h - выгрузка
Программа не должна использовать мультиплексный номер. n Программа должна сканировать мультиплексные номера с 00 h по FFh, запомнить первый свободный, т. е номер процесса, который не инсталлирован. n Программа должна сравнивать 16 байт сигнатуры для всех мультиплексных номеров, которые используются с целью определения установлена ли программа на этом номере. Если не установлена, то берется первый свободный номер. n Формат сигнатуры: offset size 00 h 08 h 10 h 8 bytes 8 bytes 64 bytes descriptor имя произв имя прогр. asciz опсание продукта
Пример использования прерывания 2 Fh int_2 Fh_vector DD ? . . . int_2 Fh proc far cmp AX, 0 B 700 h ; или 0 C 700 jne Pass_2 Fh mov AL, 0 FFh iret Pass_2 Fh: jmp dword ptr CS: [int_2 fh_vector] int_2 Fh endp ; =================== begin: mov AX, 0 B 700 h ; установить статус процесса мультиплексного прер. int 2 Fh cmp AL, 0 jz not_installed lea DX, msg call print 20 h msg DB ‘Программа уже инициализирована’, 13, 10, ‘$’ not_installed:
Выгрузка резидентной программы В DOS отсутствуют средства выгрузки резидентных программ. Единственный способ - перезагрузка компьютера. Правда есть утилиты, которые позволяют удалять резидентные программы. Резидентные программы должны иметь встроенные средства выгрузки. Рассмотрим пример. Пусть последовательно загружаются в память три резидентные программы A, B, C. Перед изменением адреса прерывания программа сохраняет адрес обработчика, а затем вызывают его в процессе своей работы. Программа A перехватывает прерывание 09 h и 21 h Программа B перехватывает прерывание 16 h и 21 h Программа C перехватывает прерывание 09 h После этого программа A удаляется из памяти
До удаления: 09 h vect Адр. обр прогр C 16 h vect Адр. обр прогр B 21 h vect Адр. обр прогр B Int 09 h vect Адр. обр прер. 09 h BIOS Int 21 h vect Адр. обр прер. 21 h DOS Int 16 h vect Адр. обр прер. 16 h BIOS Int 21 h vect Адр. обр прер. 21 h прогр. A Int 09 h vect Адр. обр прер. 09 h прогр. A Программа B Программа C
После удаления: 09 h vect Адр. обр прер. 09 h BIOS 16 h vect Адр. обр прер. 16 h прогр. B 21 h vect Адр. обр прер. 21 h DOS Int 16 h vect Адр. обр прер. 16 h BIOS Int 21 h vect Адр. обр прер. 21 h прогр. A (висячая ссылка) Int 09 h vect Адр. обр прер. 09 h прогр. A (висячая ссылка) Программа B Программа C
Функция Освободить память int 21 h AH=49 h ES сегментный адрес освобождаемого блока памяти возврат: CF=0 ошибок нет CF=1 AX=9
Пример процедуры выгрузки из памяти remove mov int mov cmp jne cmp je not_remove: proc CX, CS AX, 3509 h 21 h DX, ES CX, DX not_remove BX, offset not_remove AX, 3521 h DX, ES CX, DX not_remove BX, offset uninstall ret ; проверить вектор 09 h int_09 h ; проверить вектор 21 h inr_21 h
uninstall: push lds ; ; mov mov int lds mov int pop push pop mov int remove DS DX, int_09 h_vect DX, DS, AX, 21 h DX, AX, 21 h DS CS ES AH, 21 h ; восстановить 09 h ; Эта команда эквивалентна ; следующим двум word ptr int_09 h_vect+2 2509 h int_21 h_vect 2521 h 49 h endp
Переключение стека в резидентной программе n n При реализации процедуры прерывания (аппаратного или программного) CPU сохраняет в стеке прерванной задачи регистр флагов, сегментный регистр, регистр CS и IP и загружает из вектора прерывания в регистры CS и IP двухсловный адрес обр-ка прер-ния. Все остальные регистры хранят эту информацию, которая в них была на момент прерывания. Для того, чтобы не разрушать прерванную задачу, в самом начале обработчика прерывания следует сохранить все используемые в обработчике регистры, а перед командой iret - восстановить их. Это относится и к сегментным регистрам и к РОН. Все команды обращения к памяти используют по умолчанию в качестве сегментного регистра - регистр DS. Если при переходе в обработчик не выполнить настройку DS на сегмент обработчика, то команды вида: mov AX, mem mov BX, [SI] будут обращаться к случайным ячейкам прерванной задачи, что, возможно, приведет к разрушению и этой задачи, и обработчика. Если нежелательно перенастраивать регистр DS, то в командах работы с памятью следует использовать замену регистра: mov AX, CS: mem mov BX, CS: [SI]
n n Особая ситуация возникает со стеком. При переходе в обработчик регистры SS и SP настроены на стек прерванной задачи. Если этот стек имеет достаточный объем, то обработчик его может использовать, а если нет - переполнение стека может привести к разрушению прерванной программы. Поэтому надежнее в обработчике прерывания иметь собственный стек. Если TSR программа «паразитирует» на чужом стеке, то в этом случае использование стека должно быть минимальным. Смена стека требует запоминания кадра стека (содержимого SS и SP) в ячейках памяти отведенной обработчику, занесения в SS и SP новых значений и восстановления старого кадра перед выходом из обработчика. Естественно, что для стека должен быть выделен свободный объем (необходимый для запоминания своих данных, а может быть и чужих, от программ, «паразитирующих» на чужом стеке). Если резидентная программа не допускает повторной активизации в процессе своей работы, то можно не делать проверку переключения стека, и смена стека может быть осуществлена следующим образом:
org 100 h begin 0 0 0 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=$
n n Процедура обработчика прерывания начинается с сохранения кадра стека прерванной задачи. Адресация ячеек выполняется через CS, поскольку DS еще указывает на сегмент данных вызвавшей программы. Установка нового кадра стека всегда выполняется при запрещенных прерываниях, т. к. если аппаратное прерывание произойдет между командами заполнения SS и SP, вектор прерванного процесса будет сохранен в случайной ячейке памяти. Заполнить сегментный стека можно и так: push CS pop SS Однако это выполняется на стеке прерванной программы, приведенный же пример не затрагивает ни стека прерванной задачи, ни регистр ax, ни других регистров. Т. к. команда mov SS, CS запрещена, то содержимое cs копируется в ss через ячейку памяти mem. Команда mov SP, offset end_res заносит адрес для первого стека, место под которым выделено в самом конце резидентной части обработчика. Под стек отведено 256 слов.
n n При запуске программы на выполнение DOS находит свободную область памяти подходящего размера. В начале программы создается префикс программного сегмента (PSP) размером в 256 байт. Сама программа загружается вслед за PSP. Кроме того, DOS передает программе копию среды. Размер среды от 160 байт для MS DOS 3. 3 и выше. Сегментный адрес среды помещается в PSP по смещению 2 ch. Резидентные программы практически никогда не используют среду DOS, занимаемую ею память можно освободить с помощью функции 49 h. mov ES, word ptr DS: [2 CH] ; загрузить сегментный адрес среды в es mov AH, 49 h ; и освободить память int 21 h Резидентная программа не нуждается и в PSP. Младшая часть PSP (до смещения 5 ch) используется DOS и в последний раз потребуется при выполнении функции 31 h или прерывания 27 h. В дальнейшем DOS будет использовать PSP прерванной программы.
n n Некоторые TSR программы используют PSP программы, например, пересылают резидентную часть программы в PSP c помощью команды movsb, уменьшая тем самым размер резидентной позиции. Однако, надежнее, проще и целесообразнее найти применение PSP в резидентной программе. Например, использовав его как буфер ввод-вывод или разместив в нем собственный стек. Последнее выполняется следующим образом: вместо mov SP, offset end-res mov SP, offset start При этом получаем стек глубиной 256 байт или 128 слов, т. е. все PSP
Обработчик прерываний от таймера n n Большому количеству TSR программ необходимы постоянные по времени проверки ресурсов системы или осуществление активизации некоторых процессов. Подобные действия может обеспечить обработчик прерываний от таймера.
Векторы прерываний. Прер. 20 таймера 08 h 1 Сh Заглушка BIOS iret . . . Int 1 Сh. Прикл iret адная обраб iret отка Программа BIOS отсчета времени
Контроллер прерываний и его программирование n Если необходимо написать обработчик аппаратного прерывания – то нужно выполнить все необходимые действия: ¨ ¨ n n аппаратура, от которой пришло прерывание; микросхемы контроллера прерываний. Сигналы прерываний поступают от ВУ через контроллер прерываний (микросхема Intel 8259 A) Основное назначение контроллера – направление сигналов запросов прерываний от восьми устройств на единств. вход прерываний процессора Контроллер передает в процессор номер вектора по линиям данных. Сигнал INT поступающий на одноименный вход СРU инициирует процедуру прерывания.
Организация аппаратных прерываний в IBM РС/ХТ IRQ 0 IRQ 1 IRQ 2 IRQ 3 КОНТР ОЛЛЕР ПРЕРЫ ВАНИЙ INT СРU vector IRQ 4 IRQ 5 IRQ 6 IRQ 7 Баз. вектор – 8 Порты 20 h, 21 h IRQ - Interrupt Request Запрос прерывания
Формирование вектора прерывания 0 0 1 0 0 0 IRQ 0 0 0 1 IRQ 1 09 h клавиатура 0 0 1 0 IRQ 2 0 Ah Резерв 0 0 1 0 1 1 IRQ 3 0 Bh Сом 2 0 0 1 1 0 0 IRQ 4 0 Ch Сом 1 0 0 1 1 0 1 IRQ 5 0 Dh Жесткий диск 0 0 1 1 1 0 IRQ 6 0 Eh Гибкий диск 0 0 1 1 IRQ 7 0 Fh LPT 1 Базовый вектор 08 h таймер
В IBM PC/AT 2 контроллера прерываний IRQ 8 IRQ 9 IRQ 10 IRQ 11 IRQ 12 IRQ 13 КОНТР ОЛЛЕР ПРЕРЫ ВАНИЙ Ведо мый IRQ 0 IRQ 1 IRQ 3 IRQ 4 IRQ 5 IRQ 14 ПРЕРЫ ВАНИЙ INT СРU vector Веду щий IRQ 6 IRQ 15 КОНТР ОЛЛЕР IRQ 7 Баз. вектор – 70 h Порты А 0 h, А 1 h Базовый вектор - 8 Порты 20 h, 21 h
Соответствие векторов прерываний устройствам компьютера Прерывание IRQ 1 IRQ 2 IRQ 8 IRQ 9 IRQ 10 IRQ 11 IRQ 12 IRQ 13 IRQ 14 IRQ 15 IRQ 3 IRQ 4 IRQ 5 IRQ 6 IRQ 7 Вектор 8 h 9 h Ah 70 h 71 h 72 h 73 h 74 h 75 h 76 h 77 h Bh Ch Dh Eh Fh Устройство Таймер Клавиатура Вход от ведомого Клапан микросхемы часы realtime Программно перенапр. на IRQ 2 (int OAh) Резерв - «Мышь (PS/2) Сопроцессор Жесткий диск Резерв Сом 2 Сом 1 Принтер LPT 2 Гибкий диск LPT 1
Структура контроллера CPU INT IF INTA IRQ 0 0 0 IRQ 1 1 - 0 0 IRQ 2 0 1 x 0 IRQ 3 0 0 x 0 IRQ 4 0 1 x 0 IRQ 5 0 0 x 0 IRQ 6 0 0 x 0 IRQ 7 0 0 x 0 Регистр маски IMR Port 21 h Схема анализа приоритетов Port 20 h Регистр Запросов IRR Port 20 h x 0 1 - 0 Регистр обслуживаемых запросов ISR Port 20 h EOI
Структура программы обработки аппаратного прерывания IRQ 1 Запрещены все вложенные прерывания, независимо от их приоритетов (IRQ - IRQ 7) sti Разрешены только вложенные прерывания с более высокими приоритетами IRQ EOI Разрешены все вложенные прерывания, независимо от их приоритетов (IRQ 0 - IRQ 7) iret
Обработчик прерываний, допускающий вложенность прерываний IRQi STI Возможны прерывания более высоких уровней IRQØ – IRQ(i-1) Interrupt - IRQ Ø, . . , i, i+1, . . Возможны прерывания всех уровней MOV AL, 20 h ОUT 20 h, AL IRET EOI
Обработчик прерываний, не допускающий вложенности прерываний IRQi STI Возможны прерывания более высоких уровней IRQØ – IRQ(i-1) Запрещены все прерывания CLI MOV AL, 20 h ОUT 20 h, AL IRET EOI
Примеры программирования контроллера прерывания n mov AL, 20 h out 20 h, AL out A 0 h, AL n in AL, 21 h or AL, 1 out 21 h, AL n in Запросы на прерывания, поступающие в ведущий контроллер IRQ - IRQ 7 блокируют только ведущий контроллер. Однако запросы на прерывание, поступающие в ведомый контроллер - (IRQ 8 -IRQ 15) , блокируют уровни низших приоритетов в ведомом и IRQ 2 - IRQ 7 – в ведущем контроллере. Поэтому в программах обработки прерываний уровней 8… 15 следует предусматривать посылку команды конца прерываний в оба контроллера ; прочитать текущую маску ; установить в 1 разряд рег-ра IMR ; вернуть в IMR AL, 21 h ; прочитать текущую маску and AL, 0 FEh ; сбросить бит в out 21 h, AL ; вернуть в IMR Выполнение этих команд приведет к остановке системного таймера. Выполнение этих команд приведет к восстановлениб работы системного таймера.
Резидентный обработчик прерываний от клавиатуры с подключением до системного Аппарат. прерывание Отпускаие или нажатие клавиши Контроллер прерываний Контроллер клавиатуры CPU Адрес системного обработчика из вектора 09 h 8048 Порт 60 h Int 09 h Скен-код Кольцевой буфер ввода (16 слов) Байт флагов клавиатуры 40 h: 17 h 40 h: 1 Eh Адрес головного символа 40 h: 1 Ah Скен ASCII Адрес хвостового символа 40 h: 1 Ch Программа пользователя Программный запрос на ввод с клавиатуры 40 h: 3 Сh (1 E + 20) – 1 = 3 E – 2 = 3 C
Байт флагов клавиатуры Статус Ins Caps Lock Num Lock Scroll Lock Сост. Alt Ctrl Shift left Shift right КВ-FLAG 40 h: 17 h или можно определить КВ-FLAG следующим образом: RIGHT-SHIFT EQU клавиша правого шифта нажата LEFT-SHIFT EQU клавиша левого шифта нажата 00000001 B; 00000010 B; Клавиша Sys. Rq нажата -- // --Caps Lock -- // --Num Lock -- // --Scroll Lock -- // --Правая Alt нажата Правая Ctrl нажата Левая Alt нажата Левая Ctrl нажата
Кольцевой буфер ввода 40 h: 1 Аh BUFFER_HEAD 40 h: 1 Сh BUFFER_TAIL 40 h: 1 Eh КВ_BUFFER DW ? ; указатель головного симв. DW ? ; указатель хвостового симв. ; HEAD = TAIL - указывает, что буфер пустой DW 16 DUP (? ) ; кольцевой буфер
Пример обработчика прерывания 09 h с подключением до системного ; поле данных резидентной секции old_09 h DD ? new_09 h proc far push АХ ; Сохраним используемый регистр in AL, 60 h ; Введем скен-код сmp AL, 44 h ; Это скен-код (F 10)? je hotkey ; Да роp АХ ; Восстановим АХ jmp dword ptr [CS: old_09 h] ; В системный обработчик без возврата hotkey: ; Разрешим дальнейшую работу клавиатуры in AL, 61 h ; Введем содержимое порта В or AL, 80 h ; Установим старший бит jmp $+2 out 61 h, AL ; И вернем в порт В and AL, 7 Fh ; Снова разрешим работу клавиатуры out 61 h, AL ; Сбросив старший бит в порту В ; Пошлем приказ EOI mov AL, 20 h out 20 h, AL рор АХ iret new_09 h endp
Обработка горячей клавиши (Alt)/(F 10) new_09 h je exit 1: gogo: proc push in сmp gogo роp jmp push mov mov рор сmр je jmp far АХ AL, 60 h 44 h АХ CS: old_09 h ES AХ, 40 h ES, АХ AL, ES: 17 h ES AL, 08 h hotkey exit 1 hotkey: ; Разрешим дальнейшую работу клавиатуры in AL, 61 h or AL, 80 h jmp $+2 out 61 h, AL and AL, 7 Fh out 61 h, AL ; Пошлем приказ EOI mov AL, 20 h out 20 h, AL рор АХ iret new_09 h endp ; Сохраним используемый регистр ; Введем скен-код ; Это скен-код (F 10)? ; Да ; Восстановим АХ ; В системный обработчик без возврата ; Сохраним ES ; Настроим ES на начало ; Данных BIOS ; Получим байт флагов клавиатуры ; Восстановим ES – он больше не нужен ; (Alt) уже нажата? ; Да ; Нет, в системный обработчик ; Введем содержимое порта В ; Установим старший бит ; И вернем в порт В ; Снова разрешим работу клавиатуры ; Сбросив старший бит в порту В
Резидентный обработчик прерывания от клавиатуры с подключением после системного обработчика CODE_SEG ASSUME SEGMENT CS: CODE_SEG, DS: code_seg ORG 100 H START: JMP BEGIN int_2 Fh_vector DD ? old_09 h DD ? ; ======================================= ; ; ======================================= new_09 h proc far pushf ; В системный обработчик call CS: old_09 h ; с возвратом push AX push BX push ES mov AX, 40 h ; Настроим ES на сегментный mov ES, AX ; адрес области данных BIOS mov BX, ES: [l. Ch] ; Адрес нового хвоста dec BX ; Сместимся назад к последнему dec BX ; введенному символу cmp BX, l. Eh ; Хвост не вышел за пределы буфера? jae go ; Нет, значит он был где-то внутри буфера mov BX, 3 Ch ; Хвост после вычитания 2 вышел за пределы буфера, ; сл-но он был в самом начале, а последний введенный ; символ находится в самом конце буфера
go: mov AX, ES: [BX] ; Получим последний символ из буфера cmp AX, 1600 h ; Был введен расширенный код ASCII сочетания Alt/U? jne go__out ; Нет mov word PTR ES: [BX], OODAh ; Да, заменим код в буфере на код уголка go_out: pop ES pop BX pop AX iret new_09 h endp ; ======================================= int_2 Fh proc far cmp AX, OC 700 h jne pass_2 Fh mov AL, OFFh iret pass_2 Fh: jmp dword PTR CS: [int_2 Fh_vector] int_2 Fh endp ; ======================================= begin: mov AX, OC 700 h ; AH=OC 7 h номер процесса C 7 h ; AL=OOh -дать статус установки процесса int 2 Fh ; мультиплексное прерывание cmp AL, 0 jz not_installed ; возвращает AL=0 если не установлена
lea DX, msg call print 20 h msg DB 'Уже установлена', 13, 10, '$' not_instailed: mov AX, 352 Fh ; получить вектор int 21 h ; прерывания 2 Fh mov word ptr int_2 Fh_vector, BX ; ES: BX - вектор mov word ptr int_2 Fh_vector+2, ES mov DX, offset int_2 Fh ; получить смещение точки входа в новый ; обработчик на DX mov AX, 252 Fh ; функция установки прерывания ; изменить вектор 2 Fh int 21 h ; AL - номер прерыв. DS: DX - указатель программы обработки прер. mov AX, 3509 h ; получить вектор int 21 h ; прерывания 09 h mov word ptr old_09 h, BX ; ES: BX - вектор mov word ptr old_09 h+2, ES ; mov DX, offset new_09 h ; получить смещение точки входа в новый обработчик на DX mov AX, 2509 h ; функция установки прерывания изменить вектор 09 h int 21 h ; AL - номер прерыв. DS: DX - указатель программы обработки прер. ; ---------------------------------------mov DX, offset begin ; оставить программу. . . int 27 h ; . . . резидентной и выйти ; ======================================= PRINT PROC NEAR MOV АН, 09 H INT 21 H RET PRINT ENDP ; ======================================= CODE_SEG ENDS END START
Состояние кольцевого буфера Пусть перед вводом данного символа буфер был пуст 40 h: 1 Еh. . . Мусор . . . Голова 40 h: 1 Аh . . . Хвост 40 h: 1 Сh 40 h: ЗСh Это адрес указателя, а не его содержимое Фактически в слове, на которое указывают оба указателя, находится код символа, введенного ранее и уже изъятого программой из буфера
Состояние кольцевого буфера после ввода символа 40 h: 1 Еh. . . scan ASCII . . . Голова 40 h: 1 Аh . . . Хвост 40 h: 1 Сh 40 h: ЗСh 40 h: 1 Еh Хвост 40 h: 1 Сh. . . scan ASCII Голова 40 h: 1 Аh 40 h: ЗСh В программе после вычитания 2 из адреса хвостового элемента, проверяется находится ли полученное значение в пределах буфера. Если оно равно или больше 1 Еh, команда jae - выполняет переход на продолжение программы. Если полученное значение меньше 1 Еh, то это значит, что хвостовой указатель указывает на самое начало буфера, а занесенный только что в буфер код находится в самом его конце
Резидентный обработчик прерываний от клавиатуры с подключением как до, так и после системного CODE_SEG SEGMENT ASSUME CS: CODE_SEG, DS: code_seg ORG 100 H START: JMP BEGIN int_2 Fh_vector DD ? old_09 h DD ? tail DW 0 new_09 h proc far push AX push ES mov AX, 40 h ; Настроим ES на сегментный mov ES, AX ; адрес области данных BIOS mov AX, ES: [1 Ch] ; Сохраним адрес хвоста перед обработкой mov CS: tail, AX pop ES pop AX pushf ; В системный обработчик call CS: old_09 h ; с возвратом push AX push BX push ES mov AX, 40 h ; Настроим ES на сегментный mov ES, AX ; адрес области данных BIOS mov BX, CS: tail ; Адрес нового хвоста cmp BX, ES: [1 Ch] ; Хвост сместился? jne go_out ; нет – на выход mov AX, ES: [BX] ; Получим последний символ из буфера cmp AX, 1600 h ; Был введен расширенный код ASCII сочетания Alt/U? jne go_out ; Нет mov word PTR ES: [BX], OODAh ; Да, заменим код в буфере на код уголка go_out:
pop ES pop iret new_09 h endp int_2 Fh cmp jne mov iret pass_2 Fh: jmp int_2 Fh endp begin: mov BX AX proc far AX, OC 700 h pass_2 Fh AL, OFFh dword PTR CS: [int_2 Fh_vector] AX, OC 700 h ; AH=OC 7 h номер процесса C 7 h ; AL=OOh -дать статус установки процесса ; мультиплексное прерывание int 2 Fh cmp AL, 0 jz not_installed ; возвращает AL=0 если не установлена lea DX, msg call print 20 h msg DB 'Уже установлена', 13, 10, '$' not_instailed: mov AX, 352 Fh ; получить вектор int 21 h ; прерывания 2 Fh mov word ptr int_2 Fh_vector, BX ; ES: BX - вектор mov word ptr int_2 Fh_vector+2, ES mov DX, offset int_2 Fh ; получить смещение точки входа в новый ; обработчик на DX mov AX, 252 Fh ; функция установки прерывания ; изменить вектор 2 Fh int 21 h ; AL - номер прерыв. DS: DX - указатель программы обработки прер.
mov AX, 3509 h ; получить вектор int 21 h ; прерывания 09 h mov word ptr old_09 h, BX ; ES: BX - вектор mov word ptr old_09 h+2 , ES ; mov DX, offset new_09 h ; получить смещение точки входа в новый обработчик на DX mov AX, 2509 h ; функция установки прерывания ; изменить вектор 09 h int 21 h ; AL - номер прерыв. DS: DX - указатель программы обработки прер. ; ---------------------------------------mov DX, offset begin ; оставить программу. . . int 27 h ; . . . резидентной и выйти ; ============================================================================= PRINT PROC NEAR MOV АН, 09 H INT 21 H 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
Режимы дисплея Номер Тип Макс. цветов Формат текста Макс. Страниц Нач. адрес 0 Т 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 10 h 00 h установить видео режим 01 h установить размер и форму курсора 02 h установить позицию курсора 03 h читать позицию курсора 04 h читать световое перо 05 h выбрать активную страницу дисплея 06 h листать окно вверх (или очистить) 07 h листать окно вниз 08 h читать символ/атрибут 09 h писать символ/атрибут 0 Ah писать символ 0 Bh выбрать палитру/цвет бордюра 0 Ch писать графическую точку 0 Dh читать графическую точку 0 Eh писать символ в режиме TTY 0 Fh читать видео режим 10 h EGA уст ановить палитру 11 h EGA генератор символов 12 h EGA специальные функции 13 h писать строку (только AT + EGA )
Атрибут символа 7 6 5 4 3 2 1 0 Яркость фона или мерцание символа Цвет фона Яркость символа Цвет символа
Цвет символа Биты 0 -3 Цвет 0 черный 1 синий 2 зеленый 3 бирюзовый 4 красный 5 фиолетовый 6 коричневый 7 белый 8 серый 9 голубой А салатовый В светло-бирюзовый С розовый D светло-фиолетовый E желтый F ярко-белый Биты 4 -6 цвет фона под символом. Бит 7 – в зависимости от режима видеоодаптера определяет либо яркость фона под данным символом (тогда фон принимает 16 цветов), либо мерцание символа. Так, в режиме мерцания значения старшего полубайта атрибута 8 h обозначает не серый фон, а черный при мерцающем символе. Сh- не розовый, а красный
Очистим экран, наложив на него черно-белое окно mov AH, Al, 06 h 0 mov BH, 07 h mov mov int CH, CL, DH, DL, 10 h 0 O 24 79 ; ; ; ; ; функция задания окна режим создания (не прокрутка) атрибут всех символов в окне – ч/б верхняя Y – коорд. левая Х – коорд. нижняя Y – коорд. правая X – коорд. прер. BIOS.
0, 0 24 y 79 x
Выведем на экран цветное окно mov mov int AH, 06 h AL, 0 BH, 1 Eh CH, 5 CL, 40 DH, 9 DL, 75 10 h ; функция задания окна ; режим создания (не прокрутки) ; атрибут желтый по синему ; верхняя Y – коорд. ; левая X – коорд. ; нижняя Y – коорд. ; правая X – коорд. ; прер. BIOS
Позиционируем курсор mov mov Int AH, BH, DL, 10 h 02 h 0 7 45 ; функция позиционирования ; видеостраница ; строка ; столбец
Вывод строки символов в окно без задания атрибутов (т. е. с атрибутами окна) mov mov metka: mov Int Loop CX, len 1 ; длина строки BX, offset mes 1 ; адрес строки символа AH, 0 Eh ; вывод одного символа в реж. телетайпа AL, [Bx] ; символ в AL 10 h ; сдвиг по строке metka
; Строка вне окна, с указанием атрибутов символов mov AH, 13 h ; функция вывода строки mov AL, 0 ; режим (атрибут в BL) mov BH, 0 ; видеостраница mov BL, 04 h ; атрибут всех символов mov CX, len 2 ; длина строки mov DH, 16 ; начало позиции - строка mov DL, 25 ; начало позиции - столбец push DS ; настройка ЕS на наш сегм. pop ES ; данные mov BP, offset mes 2 ; ES: BP – выв. стр. Int 10 h ; Позицируем курсор в начало посл. строки экрана mov AH, 02 h ; функция позиционирования mov BH, O ; видеострока mov DH, 24 ; строка mov DL, 0 ; столбец Int 10 h mes 1 DB 16, ’Cтрока, выведенная в окно’, 17 len 1 = $-mes 1 mes 2 DB 22, 22, ’Строка, выведенная вне окна’, 22, 22 len 2 =$-mes 2
Работа с видеобуфером См. Слайд «Распределение адресного пространства в DOS» Текстовый видеобуфер адаптера EGA включает 8 видеостраниц и занимает 32 Кб от сегментного адреса B 800 h. Начинается он с видеостраницы 0, адрес которой B 8000 h. Объем видеостраниц 4 Кб. Видеостраница Начальный адрес 0 В 8000 1 В 9000 2 ВА 000 3 ВВ 000 4 BC 000 5 BD 000 6 BE 000 7 BF 000 До BFFFF, следующий адрес C 0000 h
Логическая организация текстового видеобуфера B 800 h: 00 B 800 h: 01 B 800 h: 02 B 800 h: 03 B 800 h: 04… Символ Атрибут Символ … знакоместо 0 знакоместо 1 знаком. . .
Принципы работы с видеобуфером n n 2 -х байтовые коды символов записываются в видеобуфер в том порядке, в каком они должны появляться на экране, т. е. первые 80 двухбайтовых полей - соответствуют первой строке, вторые 80 - второй строке и т. д. Таким образом, переход на следующую строку осуществляется не с помощью управляющих кодов возврата каретки или перевода строки, а с размещением кодов символа в другом месте буфера, в полях, соответствующих следующей строке. Вообще при формировании изображения непосредственно в видеобуфере, в обход программ DOS и BIOS, все управляющие коды ASCII теряют свои управляющие функции и отображаются в виде соответствующих им символов. Трактовка же кодов 10, 13 - ПС и ВК- выполняется программами DOS или BIOS, которые в данном случае не активизируются.
Пример программы непосредственной работы с видеобуфером mov mov AX, ES, BX, AL, 0 B 800 h ; сегментный адрес видеобуфера AX ; загрузка в ES 80*2*5 ; смещение в видеобуфере(в байтах) ’*’ ; код ASCII символа в AL ; соответствует первому (четному) ; байту знакоместа AH, 0 Eh ; атрибут- желтый на черном ; соответствует второму (нечетному) ; байту знакоместа - код атрибута ES: [BX], AX ; запись в видеобуфер ES: [BX+162], 0 B 0 Fh ; цвет светлобирюзовый по черному, ; символ с кодом ASCII Fh Выражение 80*2*5 – смещение от начала видеобуфера первого байта строки 5
Запишем строку в видеобуфер push CS ; DS на наш сегмент pop DS ; команд mov AX, 0 B 800 h ; mov ES, AX ; ES-> на видеобуфер mov SI, offset msg ; SI= адрес источника Mov DI, 80*2*12+37*2 ; DI= адрес приёмника mov CX, msglen ; CX-число пересылаемых битов cld ; сброс DF - вперед rep movsb ; пересылка в цикле ; Данные msg DB ‘П’, 1 Eh, ’р’, 1 Eh, ’и’, 1 Eh, ’в’, 1 Eh, ’е’, 1 Eh, ’т’, 1 Eh msglen=$-msg Сдвиг от начала видеобуфера составляет 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 1 Eh ; атрибут всех символов строк
Программы с несколькими сегментами команд Рассмотрим программы с расширением ЕХЕ. Любая программа, загружаемая в память, включает три компонента: nокружение ENVIRONMENT nпрефикс программы PSP nсобственно программу, в случае ЕХЕ может состоять из нескольких сегментов. CS, SS, IP и SP инициализируются заголовками из ЕХЕ-файла. Поскольку окружение и сама программа ( включая PSP) рассматриваются DOS , как отдельные блоки памяти, и та, и другая структура предваряются блоками управления памяти МСВ, размером 16 байт. С помощью этих блоков DOS ведёт учёт свободной и занятой памяти. MCB DS: [2 Сh], ES: [2 Ch] Окружение MCB PSP программа DS, ES CS
СОМ программы В этом случае единственный сегмент содержит все компоненты программы. n. PSP nкоды команд nданные nстек В терминах языков высокого уровня это соответствует минимальной или крошечной модели памяти. Преимущество. СОМ прогр. перед ЕХЕ- компакность. Как правило резидентная программа пишется в формате. СОМ. В терминах языков высокого уровня это соответствует минимальной или крошечной модели памяти PSP Программ а с данными стек IP = 0100 h SP = 0 FFFEh
Формат MCB блока смещение длина Содержимое 0 1 Тип ‘M’ (2 Dh) – за этим блоком есть еще блоки MCB Тип ‘Z’ (5 Ah) – данный блок последний 1 2 Владелец (сегм. Адрес) 3 2 Размер (число параграфов в памяти) 5 11 Зарезервировано
Пример программы с двумя сегментами команд text 1 segment ‘code’ assume CS: text 1, DS: data main proc mov AX, data mov DS, AX. . call far ptr subr 1. . call far ptr subr 2. . main endp text 1 ends text 2 segment ‘code’ assume CS: text 2, DS: data subr 1 proc far. . subr 1 endp ; subr 2 proc far. . subr 2 endp text 2 ends data segment … DB … DW. . data ends stack segment stack ‘stack’ DW 128 dup(0) stack ends end main
Модели памяти В терминах языков высокого уровня • COM - программа соответствует минимальной или крошечной модели памяти • Если команда помещается в один сегмент команд и данные в одном сегменте данных, то такая. ЕХЕ программа принадлежит к малой модели памяти. • Если требуется увеличить объём команд, то необходимо организовать несколько сегментов команд. Программа с несколькими сегментами команд и одним сегментом данных относится к средней модели памяти. В программе, содержащей несколько сегментов команд, должны быть команды либо перехода из одного сегмента в другой, либо вызов процедуры из другого сегмента. Любое обращение к другому сегменту команд носит название межсегментного или дальнего.
Сегмент команд с главной процедурой получил название text 1. Процедуры subr 1 и subr 2 объявлены с описанием far, а её вызовы в главной процедуре сопровождаются описаниями far ptr (far pointer- дальний указатель). Вызов не call, а call far ptr. Смещение код команды адрес проц. subr 1 000 A 9 A 0009 4451 call far ptr subr 1 1)CS=444 D->в стек 2)IP=000 F->в стек код операции дальнего 3)4451 -> в CS вызова 4)0009 -> в IP ret- работает в зависимости от того, как объявлена процедура ret-в дальней проц. снимает со стека два слова. ret-в ближней процедуре снимает со стека одно слово. Т. о. ближние процедуры следует вызывать только из того же сегмента командой ближнего вызова call, в то время, как процедуры, объявленные, как дальние следует вызывать только с помощью команды дальнего вызова call far ptr. Лишь в этом случае завершающие эти процедуры команды ret будут работать правильно.
Передача параметров из С программы в функцию на Ассемблере i = 25; J =4; Test (i, j, 1); _Test . MODEL small. CODE PUBLIC _Test Proc push BP mov BP, mov AX, add AX, sub AX, pop BP ret ENDP END SP SP+2 25 (i) SP+4 SP [BP+4] [BP+6] [BP+8] Return Address 4 (j) SP+6 1
Интерфейс с программами на С extern caps(char); main() { char c; for(c='a'; c <= 'z'; c++) caps (c); } func segment public caps proc near push BP mov BP, SP mov DL, [BP]+4 sub DL, 32 push DX mov AH, 2 int 21 h pop AX pop BP ret 2 caps endp func ends end
lectures arch+asm.ppt