Режими адресації пам’яті
Як при використанні операнда у пам’яті задати ту чарунку пам’яті з якою ви бажаєте працювати? Очевидна відповідь полягає в тому, щоб привласнити потрібній змінній у пам’яті ім’я, як ми це робили у останньому розділі. За допомогою, наприклад, наступних операторів ви можете вирахувати змінну пам’яті Debts (борги) зі змінної пам’яті Assets (майно):
Assets DW? Debts DW? .. mov ax,[Debts] sub [Assets],ax
В дійсності мова Асемблера забезпечує декілька різних способів адресації до рядків символів, масивів та буферів даних. Найбільш простіший спосіб полягає в тому, щоб зчитати дев’ятий по рахунку символ строки CharString:
CharString DB ‘ABCDEFGHIJKLM’ . . mov ax,@Data mov ds,ax mov al,[CharString+8]
В даному випадку це теж саме, що:
mov al,[100+8]
так як CharString починається зі зміщенням 100. Все, що замкнено у квадратні дужки, інтерпретується Турбо Асемблером, як адреса, тому зміщення Charstring та 8 складаються та використовується в якості адреси пам’яті. Інструкція приймає вигляд:
mov al,[108] Такий тип адресації, коли чарунка пам’яті створюється її ім’ям, плюс деяка константа, зветься безпосередньою (прямою) адресацією. Хоча безпосередня адресація – це добрий метод, вона не відрізняється достатньою гнучкістю, тому що звернення виконується кожний раз в одній й тій же адресі пам’яті. Тому давайте роздивимось другий, більш гнучкий шлях адресації пам’яті. Розглянемо наступний фрагмент програми, де у регістр AL також завантажується дев’ятий символ CharString:
mov bx, OFFSET CharString+8 mov al,[bx]
У даному прикладі для посилання на дев’ятий символ використовується регістр bx. Перша інструкція завантажує у регістр bx зміщення CharString (згадайте про те, що операція OFFSET повертає зміщення мітки у пам’яті), плюс 8. (Обчислення OFFSET та складання для цього виразу виконується Турбо Асемблером підчас асемблювання.) Друга інструкція визначає, що AL потрібно скласти зі змістом по зміщенню в пам’яті, на яке вказує регістр BX
mov AL,[108]
Квадратні дужки вказують, що в якості операнда – джерела повинна бути використовуватися чарунка, на яку вказує регістр BX, а не сам регістр BX. Не забувайте вказувати квадратні дужки при використанні BX в якості показника пам’яті. Наприклад:
mov ax,[bx]; завантажити AX з чарунки пам’яті, ; на яку вказує BX та mov ax,bx; завантажити у AX зміст ; регістра BX
це дві цілком різні інструкції. BX – це не єдиний регістр, котрий можна використовувати для посилання на пам’ять. Допускається також використовувати разом з необов’язковим значенням-константою або міткою регістри BP, SI та DI. Загальний вигляд операндів у пам’яті виглядає наступним чином: [базовий регістр + індексний регістр + зміщення],
де базовий регістр – це BX, індексний регістр – це SI чи DI, а зміщення – будь-яка 16-бітова константа, включно мітки та вирази. Кожний раз, коли виконується інструкція, яка використовує операнд в пам’яті, процесором 8086 ці три компоненти складаються. Кожна з трьох частин операнда у пам’яті є необов’язковою, хоча (це очевидно) ви повинні використовувати один з трьох елементів, інакше ви не отримаєте адресу у пам’яті. Ось як елементи операнда у пам’яті виглядають у іншому форматі:
BX SI чи+ чи +Зміщення BP DI (база) (індекс)
Існують 16 способів завдання адреси у пам’яті:
[зміщення] [bp+зміщення] [bx] [bx+зміщення] [si] [si+зміщення] [di] [di+зміщення] [bx+si] [bx+si+зміщення] [bx+di] [bx+di+зміщення] [bp+si] [bp+si+зміщення] [bp+di] [bp+di+зміщення]
Де зміщення – це те що можна привести до 16-бітового постійного значення.
Може здаватися, що 16 режимів адресації – це дуже багато, але якщо ще раз подивитесь на цей список, то побачите, що усі режими адресації отримують всього з декількох елементів, які комбінуються різними шляхами. Ось ще декілька способів, за допомогою яких можна, використовуючи різні режими адресації, завантажити дев’ятий символ рядка CharString у регістр AL.
CharString DB ‘ABCDEFGHIJKLM’,0 mov ax,@Data mov ds,ax mov si,OFFSET CharString+8 mov al,[si]
mov bx,8 mov al,[CharString+bx]
mov bx,OFFSET CharString mov al,[bx+8]
mov si,8 mov al,[CharString+si]
mov bx,OFFSET CharString mov di,8 mov al,[bx+di]
mov si, OFFSET CharString mov bx,8 mov al,[si+bx]
mov bx,OFFSET CharString mov si,7 mov al,[bx+si+1]
mov bx,3 mov si,5 mov al,[bx+CharString+si]
Усі ці інструкції посилаються на одну й ту ж чарунку пам’яті [CharString]+8.
У даному прикладі можна знайти декілька цікавих моментів. По-перше, повинні розуміти, що знак плюс (+), який використовується всередині квадратних дужок, має спеціальне значення.
|