- •Методичні вказівки
- •"Системне програмування та операційні системи”
- •Лабораторна робота №1
- •Загальні відомості
- •Компілятор Turbo Assembler
- •Компонування програми
- •Складові частини програми
- •Приклад побудови програми
- •Завдання до лабораторної роботи №1
- •Лабораторна робота №2
- •Програмна модель пристрою fpu
- •Варіанти завдань до лабораторної роботи №2
- •Лабораторна робота №3
- •Опис логічних операцій мови програмування асемблер
- •Приклад програми використання логічних операцій
- •Варіанти завдань до виконання лабораторної роботи №3
- •Лабораторна робота №4
- •Команди для роботи з масивами
- •Приклад програми для роботи з масивами
- •Варіанти завдань до виконання лабораторної роботи №6
- •Лабораторна робота №5
- •Команди для роботи зі стрічками
- •Приклад програми для роботи із стрічками
- •Варіанти завдань до виконання лабораторної роботи №5
- •Контрольні запитання
- •Порядок оформлення звітів до виконання лабораторних робіт
- •Література
- •Навчальне видання
- •« Системне програмування та операційні системи »
Приклад побудови програми
Згідно до прийнятої традиції виконання першої програми повинно завершитись виведенням напису “Hello World!”. Програма на мові програмування асемблер для середовища DOS має вигляд:
Data SEGMENT
Greet DB ‘Hello World!’, 13, 10, ‘$’
Data ENDS
ASSUME CS:Code, DS:Data
Code SEGMENT
Start:
mov ax, @Data ; завантаження номера сегменту
mov ds, ax
mov dx, OFFSET Greet ; вивід напису
mov ah, 9
int 21h
mov al, 0 ; повернення в систему
mov ah, 4ch
int 21h
Code ENDS
Stack_ SEGMENT STACK
DB 100h DUP(?) ; стек довжиною 256 байт
Stack_ ENDS
END Start
Дана програма складається з таких частин:
сегмент даних: Data SEGMENT … Data ENDS
сегмент команд: Code SEGMENT … Code ENDS
сегмент стеку: Stack_ SEGMENT … Stack_ ENDS
директив: ASSUME та END.
Сегменти визначають поділ програми на логічні частини, що між собою не перетинаються. В цих частинах згруповані дані, команди, а також зарезервоване місце для стеку.
Призначення директиви ASSUME є в тому, що під час виконання тих команд програми, які появляються після ASSUME і неявно посилаються на перелічені в ній регістри процесора (в даному випадку CS та DS), вона забезпечує передачу номерів сегментів з відповідними іменами (в даному випадку Code і Data) в ці регістри (відповідно CS та DS).
Директива END є останньою в записі тексту програми. Її призначення є в тому, щоб виконання програми розпочати з команди, позначеної міткою, приведеною в даній директиві.
Оскільки ініціалізація CS номером сегмента відбувається автоматично (адресою команди, поміченою міткою з команди END), залишається проініціалізувати регістр DS. Це виконується за допомогою команд:
mov ax, Data ; в ax – номер сегменту Data
mov ds, ax ; ax ds
Після ініціалізації регістрів виконується дворазове звертання до функцій DOS: для виведення напису та для завершення програми. Обидва ці звертання виконуються за допомогою переривання 21h.
Для виконання функцій цим перериванням в регістри процесора вводяться такі параметри:
з метою виведення напису
в AH – номер функції “виведення напису”: mov ah, 09h
в DX – передача зміщення тексту напису відносно DS: mov dx, OFFSET Greet
з метою завершення програми
в AH – номер функції “повернення в систему”: mov ah, 4ch
в AL – код повернення
це можна було реалізувати однією командою: mov ax, 4c00h
Завдання до лабораторної роботи №1
Скласти програму на мові програмування асемблер, що виводить на екран прізвище та ім’я студента, що виконує лабораторну роботу. Позицію екрану у яку виводити повідомлення програма повинна запитувати (введення з клавіатури без коментарів).
Лабораторна робота №2
“Математичні операції на мові програмування асемблер”
Тема. Математичні операції на мові програмування асемблер
Мета. Ознайомитись з програмною моделлю пристрою FPU та навчитись працювати з ним.
Програмна модель пристрою fpu
В програмну модель будь-якого процесора входять лише ті регістри, до яких програміст може доступитися за допомогою машинних команд. Пристрій FPU має загальну стекову організацію. Основу програмної моделі FPU складає регістровий стек з 8-ми 80-бітних регістрів даних R0-R7. В них зберігаються числа, представлені у формі з плаваючою комою в розширеному дійсному форматі. Такий формат є єдиним внутрішнім форматом чисел в FPU. В будь-який момент часу трибітове поле TOP в слові стану SW визначає регістр, який є вершиною стеку і позначається ST(0). Наприклад, у полі TOP є 011B,– вершиною стеку є регістр R3 і він вказується в командах як ST(0) або ST. Регістр R4 позначається як ST(1), …, R2 – ST(7). Операція завантаження в стек викликає декремент поля TOP і завантажує дані в нову вершину стеку. При виборці даних зі стеку, в пам’ять передається вміст поточної вершини стеку, і проводиться інкремент поля TOP.
Стек FPU має кільцеву замкнену конфігурацію; в чисельних командах допускається явне або неявне звернення до регістрів стеку з модифікацією поля TOP або без неї. В унарних операціях операндом є вміст вершини стеку, а результат заміщує операнд. В деяких бінарних операціях операндами є числа з двох верхніх регістрів стеку, а результат заміщує один з операндів. В інших операціях операнди вказуються явно.
З кожним регістром стеку асоціюється двобітний тег, сукупність яких створює слово тегів. Тег регістра R0 знаходиться в молодших бітах цього слова. Якщо в тегу записано:
00 – у відповідному регістрі є допустиме ненульове значення
01 – нуль
10 – спеціальне значення (нечисло, формат, що не підтримується, нескінченість або денормалізоване число)
11 – порожній регістр.
Решта регістри – це 16-бітні регістри керування та стану і два 48-бітні регістри вказівників команд та операнда.
Система команд. Команди FPU можна поділити на 5 груп: передачі даних; арифметичні; порівняння; трансцендентних операцій; керування. Для опису деяких команд введемо такі позначення: src – операнд, значення якого не змінюється; dst – операнд, значення якого замінюється результатом операції.
Особливості мови Assembler при роботі з FPU. Крім стандартних директив резервування пам’яті (DB, DW, DD (резервують відповідно байт, слово, подвійне слово)) є ще додаткові: DQ, DT, що резервують відповідно 64 та 80 біт.
Для того, щоб завантажити регістри FPU відповідними даними, слід скористатися командами передачі даних між регістрами стеку, а також між вершиною стеку і пам’яттю.
Команди завантаження. Є три команди завантаження: дійсних чисел (FLD src), цілих двійкових чисел (FILD src) та цілих десяткових (FBLD src). При цьому виконується декремент вказівника стеку; передається операнд у нову вершину стеку. Наприклад, команда:
FLD ST(0); копіює вершину стеку
FLD QWORD PTR [BX]; завантажує довге дійсне
FILD WORD PTR ARR[DI]; завантажує ціле слово
FBLD VOLUME; завантажує ціле десяткове.
Команди зберігання. Дві команди FST dst (дійсне) і FIST dst (ціле) передають вміст ST(0) в пам’ять без модифікації вказівника вершини стеку.
Команди зберігання з видаленням із стеку. FSTP dst (відповідник FST); FISTP dst (відповідник FIST); FBSTP dst (перетворює вміст ST(0) в упаковане ціле десяткове число). Ці команди передають вміст ST(0) в пам’ять, позначають ST(0) як нечисло і виконують інкремент вказівнику вершини стеку.
Команда обміну. FXCH dst. Dst є регістром (наприклад, ST(3)). Якщо цей операнд опустити, то виконається обмін між ST(0) та ST(1). FXCH ST(0) – холоста команда.
Команди завантаження констант.
FLDZ; 0
FLD1; 1
FLDPI; =3.141592654…
FLDL2T; двійковий логарифм 10
FLDL2E; двійковий логарифм числа e=2.71…
FLDLG2; десятковий логарифм 2
FLDLN2; натуральний логарифм 2
Завантаження проводиться так: виконується декремент вказівник вершини стеку; завантажується в нову вершину стеку константа.
Арифметичні операції. Основні арифметичні операції виконуються такими командами:
FADD (додати);
FSUB (відняти);
FMUL (помножити);
FDIV (поділити).
Ці команди можуть мати операнди за замовчуванням (ST(1)=ST(1)+ST(0)), один операнд (регістр, область пам’яті 32-х або 64-х біт) (ST(0)=ST(0)+mem64), або два операнди-регістри (FADD ST(0), ST(4); ST(0)=ST(0)+ST(4)). Якщо до мнемоніки команди додати в кінці ‘P’, то операнд scr видаляється зі стеку; якщо після літери ‘F’ додати ‘I’, то така команда вимагає одного операнда – цілого 16-ти або 32-х біт (dst в цьому випадку є ST(0)).
FSQRT обчислює квадратний корінь з ST(0) і результат поміщає знову ж в ST(0).
FSCALE виконує операцію ST(0)=ST(0)*2ST(1).
FABS виконує ST(0)=|ST(0)|.
FCHS – ST(0)=-ST(0).
FSIN, FCOS – аргумент в ST(0) в радіанах; результат поміщається в ST(0)
FPATAN обчислює арктангенс від частки ST(1)/ST(0). Як приклад розглянемо обчислення арксинуса за допомогою цієї команди: arcsin(x)=arctg(x/((1-x2)1/2)
Занести x в стек
Обчислити і включити в стек x/((1-x2)1/2
Виконати команду FPATAN
F2XM1 обчислює Y=2X-1. Значення X береться з ST(0) і повинно знаходитись в межах від –1 до +1. За допомогою цієї команди можна підняти до степені X будь-яке число Y: YX=2Xlog2(Y).
FYL2X обчислює двійковий логарифм числа: ST(0)=ST(1)*log2(ST(0))
FYL2XP1 – ST(0)=ST(1)*log2(ST(0)+1)
Команда порівняння. FCOM порівнює ST(0) з src, де src може бути регістром або областю пам’яті. Після цього слід застосувати команди FSTSW AX і SAHF для того, щоб результати порівняння потрапили в регістр прапорців, а далі, за допомогою звичайних команд умовного переходу (JE, JNE, JA, JAE, JB, JBE, JP(для перевірки операндів-нечисел), …) можна реагувати на наслідки порівняння.
