Учебники

Сборка — Режимы адресации

Большинство инструкций на ассемблере требуют обработки операндов. Адрес операнда предоставляет место, где хранятся данные, подлежащие обработке. Некоторые инструкции не требуют операнда, в то время как некоторые другие инструкции могут требовать один, два или три операнда.

Когда инструкции требуется два операнда, первый операнд обычно является пунктом назначения, который содержит данные в регистре или ячейке памяти, а второй операнд является источником. Источник содержит либо данные для доставки (немедленная адресация), либо адрес (в регистре или памяти) данных. Как правило, исходные данные остаются неизменными после операции.

Три основных режима адресации —

  • Регистрация адресации
  • Немедленная адресация
  • Адресация памяти

Регистрация адресации

В этом режиме адресации регистр содержит операнд. В зависимости от инструкции регистр может быть первым операндом, вторым операндом или обоими.

Например,

MOV DX, TAX_RATE   ; Register in first operand
MOV COUNT, CX	   ; Register in second operand
MOV EAX, EBX	   ; Both the operands are in registers

Поскольку обработка данных между регистрами не требует памяти, она обеспечивает самую быструю обработку данных.

Немедленная адресация

Непосредственный операнд имеет постоянное значение или выражение. Когда инструкция с двумя операндами использует немедленную адресацию, первый операнд может быть регистром или ячейкой памяти, а второй операнд является непосредственной константой. Первый операнд определяет длину данных.

Например,

BYTE_VALUE  DB  150    ; A byte value is defined
WORD_VALUE  DW  300    ; A word value is defined
ADD  BYTE_VALUE, 65    ; An immediate operand 65 is added
MOV  AX, 45H           ; Immediate constant 45H is transferred to AX

Прямая адресация памяти

Когда операнды указываются в режиме адресации памяти, требуется прямой доступ к основной памяти, обычно к сегменту данных. Этот способ адресации приводит к более медленной обработке данных. Чтобы найти точное местоположение данных в памяти, нам нужен начальный адрес сегмента, который обычно находится в регистре DS, и значение смещения. Это значение смещения также называется действующим адресом .

В режиме прямой адресации значение смещения указывается непосредственно как часть инструкции, обычно указывается именем переменной. Ассемблер вычисляет значение смещения и поддерживает таблицу символов, в которой хранятся значения смещения всех переменных, используемых в программе.

При прямой адресации в памяти один из операндов ссылается на ячейку памяти, а другой операнд ссылается на регистр.

Например,

ADD	BYTE_VALUE, DL	; Adds the register in the memory location
MOV	BX, WORD_VALUE	; Operand from the memory is added to register

Прямая смещение адресации

Этот режим адресации использует арифметические операторы для изменения адреса. Например, посмотрите на следующие определения, которые определяют таблицы данных —

BYTE_TABLE DB  14, 15, 22, 45      ; Tables of bytes
WORD_TABLE DW  134, 345, 564, 123  ; Tables of words

Следующие операции обращаются к данным из таблиц в памяти в регистры —

MOV CL, BYTE_TABLE[2]	; Gets the 3rd element of the BYTE_TABLE
MOV CL, BYTE_TABLE + 2	; Gets the 3rd element of the BYTE_TABLE
MOV CX, WORD_TABLE[3]	; Gets the 4th element of the WORD_TABLE
MOV CX, WORD_TABLE + 3	; Gets the 4th element of the WORD_TABLE

Косвенная адресация памяти

В этом режиме адресации используется способность компьютера « Сегмент: смещение» . Обычно для этой цели используются базовые регистры EBX, EBP (или BX, BP) и регистры индекса (DI, SI), закодированные в квадратных скобках для ссылок на память.

Косвенная адресация обычно используется для переменных, содержащих несколько элементов, таких как массивы. Начальный адрес массива хранится, скажем, в регистре EBX.

В следующем фрагменте кода показано, как получить доступ к различным элементам переменной.

MY_TABLE TIMES 10 DW 0  ; Allocates 10 words (2 bytes) each initialized to 0
MOV EBX, [MY_TABLE]     ; Effective Address of MY_TABLE in EBX
MOV [EBX], 110          ; MY_TABLE[0] = 110
ADD EBX, 2              ; EBX = EBX +2
MOV [EBX], 123          ; MY_TABLE[1] = 123

Инструкция MOV

Мы уже использовали инструкцию MOV, которая используется для перемещения данных из одного пространства хранения в другое. Инструкция MOV принимает два операнда.

Синтаксис

Синтаксис инструкции MOV —

MOV  destination, source

Инструкция MOV может иметь одну из следующих пяти форм —

MOV  register, register
MOV  register, immediate
MOV  memory, immediate
MOV  register, memory
MOV  memory, register

Пожалуйста, обратите внимание, что —

  • Оба операнда в операции MOV должны быть одинакового размера
  • Значение исходного операнда остается неизменным

Инструкция MOV порой вызывает двусмысленность. Например, посмотрите на утверждения —

MOV  EBX, [MY_TABLE]  ; Effective Address of MY_TABLE in EBX
MOV  [EBX], 110	      ; MY_TABLE[0] = 110

Не ясно, хотите ли вы переместить байтовый эквивалент или словесный эквивалент числа 110. В таких случаях целесообразно использовать спецификатор типа .

В следующей таблице приведены некоторые общие спецификаторы типов —

Тип Спецификатор Байт адресован
БАЙТ 1
СЛОВО 2
DWORD 4
QWORD 8
Тбайт 10

пример

Следующая программа иллюстрирует некоторые из концепций, обсужденных выше. Он сохраняет имя «Zara Ali» в разделе данных памяти, затем программно меняет его значение на другое имя «Nuha Ali» и отображает оба имени.

Live Demo

section	.text
   global_start     ;must be declared for linker (ld)
_start:             ;tell linker entry point
	
   ;writing the name 'Zara Ali'
   mov	edx,9       ;message length
   mov	ecx, name   ;message to write
   mov	ebx,1       ;file descriptor (stdout)
   mov	eax,4       ;system call number (sys_write)
   int	0x80        ;call kernel
	
   mov	[name],  dword 'Nuha'    ; Changed the name to Nuha Ali
	
   ;writing the name 'Nuha Ali'
   mov	edx,8       ;message length
   mov	ecx,name    ;message to write
   mov	ebx,1       ;file descriptor (stdout)
   mov	eax,4       ;system call number (sys_write)
   int	0x80        ;call kernel
	
   mov	eax,1       ;system call number (sys_exit)
   int	0x80        ;call kernel

section	.data
name db 'Zara Ali '

Когда приведенный выше код компилируется и выполняется, он дает следующий результат —