
- •Просте макровизначення
- •Використання параметрів у макрокомандах
- •Вивід на екран.
- •Процедура підготовки даних до виводу на екран
- •Блок – схема алгоритму перетворення шістнадцяткового значення у ascii – код
- •Процедура переводу з шістнадцяткової в десяткову систему числення
- •Блок – схема алгоритму перетворення шістнадцяткового значення в десяткове
- •Ввід з клавіатури
- •Процедура вводу даних з клавіатури
- •Блок – схема алгоритму перетворення ascii – коду в шістнадцяткове значення
- •Процедура переводу з десяткової в шістнадцяткову систему числення
- •Блок – схема алгоритму перетворення десяткового значення в шістнадцяткове
- •Контрольні запитання:
- •Завдання:
- •Приклад виконання.
Засоби системного програмування
Лабораторна робота № 6.
Використання макрокоманд та процедур.
Ввід даних з клавіатури та вивід результату на екран.
Мета: набути навиків написання макрокоманд та процедур на Асемблері, освоїти способи передачі параметрів.
Реалізувати ввід та вивід даних в десятковій системі числення.
Процедури та оператор CALL
Процедура – це частина програми, яка може бути описана в довільному місці і містити дії над довільними даними. Процедура починається директивою PROC та завершується директивою ENDP. Кодовий сегмент може містити будь-яку кількість процедур, що розділяються директивами PROC і ENDP. Типова організація багато процедурної програми приведена нижче. Виклик процедури здійснюється командою CALL. Для повернення з процедури використовується команда RET.
Рис.1.Виклик процедур.
Зверніть увагу на наступні особливості:
- директиви PROC по мітках B10 і C10 мають операнд NEAR для вказівки того, що ці процедури знаходяться в поточному кодовому сегменті. У багатьох випадках, цей операнд опускається, тому що за замовчуванням асемблер приймає тип NEAR.
- Кожна процедура має унікальне ім'я і містить власну директиву ENDP для вказівки кінця процедури.
- Для передачі керування в процедурі BEGIN маються дві команди: CALL B10 і CALL C10. У результаті першої команди CALL керування передається процедурі B10 і починається її виконання. Досягши команди RET, керування повертається на команду безпосередньо наступну за CALL B10. Друга команда CALL діє аналогічно - передає керування в процедуру C10, виконує її команди і повертає керування по команді RET.
- Команда RET завжди виконує повернення у вихідну програму. Програма BEGIN викликає процедури B10 і C10, що повертають керування назад у BEGIN. Для виконання самої програми BEGIN операційна система DOS викликає її, і наприкінці виконання команда RET повертає керування в DOS. Якщо процедура B10 не містить завершальної команди RET, то виконання команд продовжиться з B10 безпосередньо в процедурі C10. Якщо процедура C10 не містить команди RET, то будуть виконуватися команди, що йдуть за процедурою C10 з непередбаченим результатом.
Використання процедур дає гарну можливість організувати логічну структуру програми. Крім того, операнд для команди CALL можуть мати значення, що виходять за межу від -128 до +127 байт.
Технічно керування в процедуру типу NEAR може бути передане за допомогою команд переходу чи навіть звичайним порядковим кодуванням. Але в більшості випадків рекомендується використовувати команду CALL для передачі керування в процедуру і команду RET для повернення.
Макрозасоби
Для кожної закодованої команди асемблер генерує одну машинну команду. Але для кожного закодованого оператора компіляторної мови Pascal чи C генерується один чи більш (частіше багато) команд машинної мови. У цьому відношенні можна вважати, що компіляторна мова складається з макрооператорів.
Асемблер також має макрозасоби, але макроси тут визначаються програмістом. Для цього задається ім'я макросу, директива MACRO, різні асемблерні команди, що повинний генерувати даний макрос і для завершення макровизначення - директива MEND. Потім у будь-якім місці програми, де необхідне виконання визначених у макрокоманді команд, досить закодувати ім'я макросу. У результаті асемблер згенерує необхідні команди.
Використання макрокоманд дозволяє:
- спростити і скоротити вихідний текст програми;
- зробити програму більш зрозумілої;
- зменшити кількість можливих помилок кодування.
Прикладами макрокоманд можуть бути операції вводу-виводу, пов’язані з ініціалізацією регістрів і виконання переривань перетворення ASCII і війкового форматів даних, арифметичні операції над довгими полями, обробка рядкових даних, ділення за допомогою віднімання.
Просте макровизначення
Макровизначення повинне знаходитися до визначення сегмента. Розглянемо приклад простого макровизначення по імені INIT1, що ініціалізує сегментні регістри для EXE-програми:
Рис.2 просте макровизначення.
Директива MACRO вказує асемблеру, що наступні команди до директиви ENDM є частиною макровизначення. Ім'я макрокоманди - INIT1, хоча тут можливі інші правильні унікальні асемблерні імена. Директива ENDM завершує макровизначення. Сім команд між директивами MACRO і ENDM складають тіло макровизначення.
Імена, на які є посилання в макровизначенні, CSEG, DSEG і STACK повинні бути визначені де-небудь в іншому місці програми. Макрокоманда INIT1 може використовуватися в кодовому сегменті там, де необхідно ініціалізувати регістри. Коли асемблер аналізує команду INIT1, він спочатку переглядає таблицю мнемокодів і, не знайшовши там відповідного елемента, перевіряє макрокоманди. Оскільки програма містить визначення макрокоманди INIT1 асемблер підставляє тіло макровизначення, генеруючи необхідні команди - макророзширення. Програма використовує розглянуту макрокоманду тільки один раз, хоча є інші макрокоманди, призначені для будь-якої кількості застосувань і для таких макрокоманд асемблер генерує однакові макророзширення.
Використання параметрів у макрокомандах
У попередньому макровизначенні були потрібні фіксовані імена сегментів: CSEG, DSEG і STACK. Для того, щоб макрокоманда була більш гнучкою і могла приймати будь-як імена сегментів, визначимо ці імена, як формальні параметри:
INIT2 MACRO CSNAME,DSNAME,SSNAME ; Формальні параметри
ASSUME CS:CSNAME,DS:DSNAME,SC:SSNAME,ES:DSNAME
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSNAME
MOV DS,AX
MOV ES,AX
ENDM ;Кінець макровизначення
Формальні параметри в макровизначенні вказують асемблеру на відповідність їхніх імен будь-яким аналогічним іменам у тілі макровизначення. Усі три формальних параметри CSNAME, DSNAME і SSNAME зустрічаються в директиві ASSUME, а параметр DSNAME ще й у наступній команді MOV. Формальні параметри можуть мати будь-які правильні асемблерні імена, що не обов'язково збігаються іменами в сегменті даних.
Тепер при використанні макрокоманди INIT2 необхідно вказати як параметри дійсні імена трьох сегментів у відповідній послідовності. Наприклад, наступна макрокоманда містить три параметри, що відповідають формальним параметрам у вихідному макровизначенні:
Макровизначення: INIT2 MACRO CSNAME, DSNAME, SSNAME (формальні параметри)
Макрокоманда: INIT2 CSEG, DSEG, STACK (фактичні параметри)
Оскільки асемблер уже визначив відповідність між формальними параметрами й операторами в макровизначенні, то тепер йому залишається підставити параметри макрокоманди в макророзширенні:
Параметр 1: CSEG ставиться у відповідність з CSNAME у макровизначенні. Асемблер підставляє CSEG замість CSNAME у директиві ASSUME.
Параметр 2: DSEG ставиться у відповідність з DSNAME у макровизначенні. Асемблер підставляє DSEG замість двох DSNAME: у директиві ASSUME і в команді MOV.
Параметр 3: STACK ставиться у відповідність з SSNAME у макровизначенні. Асемблер підставляє STACK замість SSNAME у директиві ASSUME.
Макровизначення з формальними параметрами і відповідні макророзширення приведені на рис.3.
Формальний параметр може мати будь-яке правильне асемблерне ім'я (включаючи ім'я регістра, наприклад, CX), що у процесі асемблювання буде замінено на параметр макрокоманди. В одній макрокоманді може бути визначене будь-яка кількість формальних параметрів, розділених комами, аж до 120 стовпчика в рядку.
TITLE
MACRO2
(EXE)
; Використання параметрів
;
------------------------------------------------
INIT2
MACRO
CSNAME,DSNAME,SSNAME
ASSUME
CS:CSNAME,DS:DSNAME,SS:SSNAME,ES:DSNAME
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSNAME
MOV DS,AX
MOV ES,AX
ENDM
;Кінець макрокоманди
;
------------------------------------------------
0000
STACK SEGMENT PARA STACK 'Stack'
0000 20 [ ???? ]
DW 32 DUP(?)
0040
STACK ENDS
;
------------------------------------------------
0000
DSEG SEGMENT PARA 'Data'
0000 54 65 73 74 20 6F
MESSAGE DB 'Test of macro', '$'
66 20 6D 61 63 72
6F 24
000E
DSEG ENDS
;
------------------------------------------------
0000
CSEG SEGMENT PARA 'Code'
0000
BEGIN PROC FAR
INIT2
CSEG,DSEG,STACK
0000 1E
+ PUSH DS
0001 2B C0
+ SUB AX,AX
0003 50
+ PUSH AX
0004 B8 ---- R
+ MOV AX,DSEG
0007 8E D8
+ MOV DS,AX
0009 8E C0
+ MOV ES,AX
000B
B4
09 MOV
AH,09
;Вивід на екран
000D
8D
16 0000 R
LEA
DX,MESSGE
;Повідомлення
0011 CD 21
INT 21H
0013 CB
RET
0014
BEGIN ENDP
0014
CSEG ENDS
END BEGIN
Рис3.
Використання
параметрів в макрокомандах.