Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
LABA06_2012.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
442.37 Кб
Скачать

Засоби системного програмування

Лабораторна робота № 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. Використання параметрів в макрокомандах.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]