Автоинкрементная и автодекрементная адресация

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

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

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

Пример:

.text

main:

movl $0x12345, %eax /* записать в регистр константу 0x12345

*/

movl %eax, %ecx /* записать в регистр %ecx операнд,

который находится в регистре %eax */

Относительная адресация

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

Автоинкрементная и автодекрементная адресация - student2.ru

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

Рассмотрим два примера:

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

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

Главный недостаток относительной адресации - большое время вычисления физического адреса операнда. Но существенное преимущество этого способа адресации заключается в возможности создания "перемещаемых" программ - программ, которые можно размещать в различных частях памяти без изменения команд программы. То же относится к программам, обрабатывающим по единому алгоритму информацию, расположенную в различных областях ЗУ. В этих случаях достаточно изменить содержимое базового адреса начала команд программы или массива данных, а не модифицировать сами команды. По этой причине относительная адресация облегчает распределение памяти при составлении сложных программ и широко используется при автоматическом распределении памяти в мультипрограммных вычислительных системах.

Лекция 5: Команды ассемблера

Команда mov

Синтаксис:

mov источник, назначение

Команда mov производит копирование источника в назначение. Рассмотрим примеры:

/*

* Это просто примеры использования команды mov,

* ничего толкового этот код не делает

*/

.data

some_var:

.long 0x00000072

other_var:

.long 0x00000001, 0x00000002, 0x00000003

.text

.globl main

main:

movl $0x48, %eax /* поместить число 0x00000048 в %eax */

movl $some_var, %eax /* поместить в %eax значение метки

some_var, то есть адрес числа в

памяти; например, у автора

содержимое %eax равно 0x08049589 */

movl some_var, %eax /* обратиться к содержимому переменной;

в %eax теперь 0x00000072 */

movl other_var + 4, %eax /* other_var указывает на 0x00000001

размер одного значения типа long - 4

байта; значит, other_var + 4

указывает на 0x00000002;

в %eax теперь 0x00000002 */

movl $1, %ecx /* поместить число 1 в %ecx */

movl other_var(,%ecx,4), %eax /* поместить в %eax первый

(нумерация с нуля) элемент массива

other_var, пользуясь %ecx как

индексным регистром */

movl $other_var, %ebx /* поместить в %ebx адрес массива

other_var */

movl 4(%ebx), %eax /* обратиться по адресу %ebx + 4;

в %eax снова 0x00000002 */

movl $other_var + 4, %eax /* поместить в %eax адрес, по

которому расположен 0x00000002

(адрес массива плюс 4 байта --

пропустить нулевой элемент) */

movl $0x15, (%eax) /* записать по адресу "то, что записано

в %eax " число 0x00000015 */

Внимательно следите, когда вы загружаете адрес переменной, а когда обращаетесь к значению переменной по её адресу. Например:

movl other_var + 4, %eax /* забыли знак $, в результате в %eax

находится число 0x00000002 */

movl $0x15, (%eax) /* пытаемся записать по адресу

0x00000002 - > получаем segmentation

fault */

movl 0x48, %eax /* забыли $, и пытаемся обратиться по

адресу 0x00000048 - > segmentation

fault */

Команда lea

lea - мнемоническое от англ. Load Effective Address. Синтаксис:

lea источник, назначение

Команда lea помещает адрес источника в назначение. Источник должен находиться в памяти (не может быть непосредственным значением - константой или регистром). Например:

.data

some_var:

.long 0x00000072

.text

leal 0x32, %eax /* аналогично movl $0x32, %eax */

leal some_var, %eax /* аналогично movl $some_var, %eax */

leal $0x32, %eax /* вызовет ошибку при компиляции,

так как $0x32 - непосредственное

значение */

leal $some_var, %eax /* аналогично, ошибка компиляции:

$some_var - это непосредственное

значение, адрес */

leal 4(%esp), %eax /* поместить в %eax адрес предыдущего

элемента в стеке;

фактически, %eax = %esp + 4 */

Наши рекомендации