Читайте также:
|
|
Використання сервісних підпрограм. Одним з основних засобів, що є у розпорядженні системного програміста, є набір службових підпрограм базової системи введення-виводу (BIOS) і операційної системи (ОС). їх використання позбавляє від необхідності настроюватися на роботу кожного конкретного пристрою, розробляти кожного разу наново службові базові процедури і, оскільки ці підпрограми є стандартними, підвищує сумісність програм.
У DOS доступ до службових підпрограм (їх називають функціями) здійснюється за допомогою програмних переривань, що викликаються по команді INT. Як огіеранд цієї команди указується номер переривання.
Всього є 256 номерів, частина з них не використовується. Підпрограм значно більше, тому їх групують і призначають номер переривання цілій групі. При виклику переривання уточнюють, до якої підпрограми потрібно звернутися. Найчастіше для цього використовують регістр АН — в нього заносять безпосередньо перед викликом переривання номер функції. Приклад виклику 1-ої функції переривання 21h:
mov ah, 1
int 21h
В результаті виконання команди INT управління передається програмі обробки відповідного переривання (в даному випадку 21h); після закінчення роботи управління повертається в перервапу програму.
Багато функцій потребують певних вхідних даних, що визначають результат її роботи. Регістри, через які ці дані передаються, називаються вхідними. Також функція може повертати певний результат — у вихідних регістрах. Таким чином, в загальному випадку процедуру виклику N-й функції переривання X можна записати так:
;заповнення вхідних регістрів
mov ah, N;АН = номер
функції
int X;вызов переривання
X
/аналіз вихідних регістрів
По номеру переривання можна визначити, чи відноситься дана підпрограма до BIOS, DOS або є призначеною для користувача.
Більшість службових підпрограм DOS зведені в переривання 21h. Серед них — функції для введення з клавіатури і виводу на екран, функції роботи з файлами, управління пам'яттю і процесами та інші. Інформацію про номери функцій і переривань, вхідні і вихідні регістри, а також опис дії функцій можна знайти в довідниках по MS-DOS.
У лабораторній роботі 1 нами викликалися дві функції: 9 — виведення ASCII$-CTpoKH на екран, і 4Ch — завершення роботи програми. Функція 4Ch є виключенням з правила: після закінчення її роботи управління повертається не програмі, що викликала, а батьківському процесу, що запустив програму (наприклад, командному інтерпретатору).
Вивід на екран. У DOS є стандартні функції виведення символьних даних: 2, 6, 9 і 40h. Нижче приводиться їх опис:
к> у АН | Опис | Вхід | Вихід |
h | Виведення символу в БТБОиТ | DL ASCII-код символу | |
h | Виведення символу в ЗТБОиТ | DL ASCIІ-код символу (окрім OFFh) | _ |
h | Виведення АБСІІ$-строки в БТБОиТ | DS:DX ASCII$-CTpOKy | — |
Oh | Виведення АБСІ12-строки на пристрій або у файл | DS: DX ASCIIZ-строку; CX довжина рядка в байтах; ВХ - № пристрою/файлу (1 ДЛЯ STDOUT) | СЕ = 0 при отсутствии помилок; АХ = число записаних байт |
Стандартним пристроєм виведення STDOUT в більшості випадків є екран, проте можна перенаправляти вивід, тобто як STDOUT використовувати інший пристрій або файл (наприклад, команда tasm > options.Ist перенаправить список опцій запуску, що виводиться асемблером, у файл options.Ist).
Цикли. Цикли в програмах на асемблері реалізуються за допомогою команд передачі управління JMP (безумовний перехід), Jxx (умовний перехід) і LOOP ("петливши").
За допомогою команди JMP можна здійснювати переходи назад (так можуть створюватися нескінченні цикли):
metka:
...; (тілс циклу)
jmp metka; перехід назад
або переходи вперед (обхід певної ділянки програми):
jmp metka; перехід вперед
metka:
Часто в тіло циклу поміщають команду умовного переходу для забезпечення можливості виходу з циклу (або передбачають можливість переривання виконання тіла циклу по натисненню CTRL-C або Ctrl-Break).
Команд умовного переходу Jxx декілька (замість хх указується символ або набір символів, що визначають умову переходу). Як і в команді JMP, як операнд указується мітка переходу, і ця мітка може указуватися як до команди переходу (перехід назад), так і після (перехід вперед).
Більшість з команд умовних переходів передають управління на вказану мітку залежно від стану прапорів процесора. Наприклад, команда JZ metka передає управління на мітку metka, якщо встановлений прапор нуля (Jump if Zero, ZF=1), JC — якщо встановлений прапор перенесення (Jump if Carry, CF = 1), a JS — якщо встановлений прапор знаку (Jump if Sign, SF = 1) і т. д. Якщо ж відповідний прапор скинутий, управління передається на наступну після Jxx команду. Також є команди, передавальні управління на вказану мітку, якщо відповідний прапор скинутий (JNZ — Jump if Not Zero, ZF = 0; JNC — Jump if No Carry, CF = 0 і т, д.).
Щоб користуватися такими командами, необхідно знати, в якому стані може знаходитися певний прапор і які команди впливають на його стан. Часто застосовують схему використання команд умовного переходу, при якій немає необхідності стежити за прапорами. Ось ця схема у вигляді фрагмента коди і блок-схеми:
metka:
cmp jxx
Команда CMP (Compare) проводить порівняння операндів (за допомогою
віднімання другого з першого) і відповідно до результату
порівняння формує
прапори (так само, як і команда звичайного віднімання SUB). При цьому в мнемонічному позначенні команд переходу указується не
(переход ПО
операцді, оішранд2 metka
(проверка
прапор, що перевіряються, а результат порівняння. Наприклад, команда JE передає управління на мітку, якщо порівнювані операнди були рівні (Jump if Equal), а команда JNE - якщо не рівні (Jump if Not Equal). (Якщо порівнювані командою CMP операнди рівні, то результат віднімання одного операнда з першого дасть нульовий результат і встановиться прапор нуля ZF. Команда JE перевірить цей прапор і передасть управління на мітку точно так, як і команда JZ. Насправді JZ і JE — різні позначення однієї машинної команди процесора, створені для зручності програмування).
Окрім команд JE (JNE) часто доводиться користуватися командами JA (Jump if Above — перехід, якщо вище), JB (Jump if Below — перехід, якщо нижче), JG (Jump if Greater — перехід, якщо більше), JL (Jump if Less — перехід, якщо менше) і їх антиподами JNA, JNB, JNG і JNL відповідно. Поняття "вище" і "нижче" відносяться до порівняння беззнакових операндів, а "більше" і "менше" — знакових (у додатковому коді).
Цикл з передумовою організовується вказівкою команди Jxx на початку JMP-цикла, з умовою поста — в кінці (у будь-якому випадку до мітки початку циклу повинна бути проинициализирована змінна циклу).
; Цикл з передумовою
raetka:
jxx exit
...; (тіло циклу)
jmp raetka -.
exit:
; Цикл з умовою поста,/ '
met ka: '
; (тіло циклу) і х \
jxx exit ''о^-ІМ I
■ і-. 'Огг *
jmp metka --/JJy \
exit: '"••Ч.. 1
■*. t і m
I Li: j
Цикл, організований тільки командою Jxx, — завжди цикл з умовою поста. Цей варіант циклу простіший, ніж організований за допомогою двох команд переходу.
Для утворення циклу команд умовного переходу часто немає необхідності вводити окрему змінну для лічильника циклу, оскільки вже є яка-небудь змінна (або навіть декілька), що циклічно міняє своє значення. Вихід з циклу можна здійснити після досягнення цієї
певного значення. Інакше йде справа з циклами, утвореними за допомогою команди LOOP. Ця команда спеціально призначена для організації циклів і завжди використовує регістр СХ як лічильник циклу.
Як операнд команди LOOP також указується мітка переходу. Команда LOOP зменшує значення регістра СХ на 1 і потім порівнює його з нулем. Якщо значення СХ не рівне 0, LOOP передає управління на вказану мітку, якщо рівно — управління передається на наступну за LOOP команду.
Перед початком циклу необхідно заповнити регістр СХ початковим значенням N (приклад нижчий). При цьому тіло цикл буде виконаний N разів, а команда LOOP передасть управління на мітку (N- 1) разів.
; Цикл, N разів, що повторюється mov сх, N
metka:
...; (тіло циклу)
loop metka
Як ілюстрація розглянемо текст програми виводу на екран рядка ASCII-символов з кодами від 32 до 255 (коди 0-31 часто використовуються як керівники). Для заповнення області пам'яті використовуємо LOOP-цикл, а для виведення отриманої послідовності на екран - функцію виведення 40h int 21h. Використанню функції 9 в даному випадку перешкоджає наявність в рядку символу '$' (код 36), який інтерпретується функцією як ознака кінця рядка.
; Лістинг 2. Виведення рядка ASCII-символов на екран oursg segment
assume es:oursg, ds:oursg symb db 224 dup('*'); резервуємо місце
(рядок) в пам'яті begin:
mov ах, oursg; сегментна адреса
даних
mov ds, ах; засилаємо в DS
; Заповнення рядка в пам'яті символами
mov сх/ 224; число повторень
циклу (256-32)
mov al, 32; починаємо з
пропуску (32)
mov si, 0; індекс усередині
відведеного рядка пам'яті
m: mov [symb+si], al; пересилаємо
символ з AL в чергову позицію
; відведеного рядка, затираючи зірочку inc аі; збільшуємо AL
(код символу) на 1
inc si; і індекс наший
рядки (наступна позиція)
loop пі; повтор
; Виведення рядка-результату на екран
mov ah, 40h; номер функції
DOS зиведення рядка
mov сх, 224; довжина рядка,
що виводиться (у байтах)
mov bx, 1; 1 - вивід на
екран
mov dx, offset symb; відносна адреса
рядка, що виводиться
int 21h; виклик DOS
; Завершення програми
mov ах, 4C00h; AH = 4Ch, AL = 0
(код виходу)
int 21h
oursg ends
end begin
Для вказівки черговій позиції рядка в пам'яті використовувалася індексна адресація з регістром SI (можна було б також використовувати DI або ВХ). Вказану адресу почала рядки (symb) складається з вмістом регістра SI (індексування), результат розглядається як відносна адреса (offset), яка в сукупності з сегментною адресою (вміст регістра DS) дає повну адресу необхідного осередку.
Інший можливий варіант — використання непрямої адресації без зсуву, коли в регістр SI (DI або ВХ) поміщається адреса почала рядки, який потім так само в циклі збільшується на І:
mov [si], al; засилаємо символ
в рядок
inc si
(Команда INC проводить збільшення операнда на 1. Для зменшення операнда на І служить команда DEC).
завдання
Зарезервувати в пам'яті рядок, заповнити його в циклі ASCII- символами в діапазоні (32., 254) з вказаним кроком, а потім видати цей рядок на екран за допомогою функції 40h DOS (int 21h). У таблиці варіантів вказані а) порядок проходження код символів (від менших до великих або навпаки, що змінюються на 1, 2 або 3), би) порядок заповнення рядка (прямій — від молодших байтів до старших, або зворотний — від старших до молодших), в) спосіб організації циклу (командою Jxx або LOOP, з пост- або передумовою). У протокол роботи включити блок-схему програми.
Варіанти:
Дата добавления: 2014-12-19; просмотров: 121 | Поможем написать вашу работу | Нарушение авторских прав |