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

Мы можем взять вычисленный таким (сложным) образом адрес и не обращаться к памяти по этому адресу, а просто положить этот адрес в регистр

Пример: хотим вычислить адрес какого-то элемента массива, который лежит в какой-нибудь структуре

Мы записываем этот адрес так, как мы привыкли, и с помощью инструкции lea (load effective address, загрузить действительный адрес) загружаем этот действительный адрес в регистр

Как правильно читать документацию на сайте https://www.felixcloutier.com/x86/?

Первый аргумент — регистр (r32), второй — адрес в памяти (m)

Screenshot 2021-11-17 at 02.53.53.png

Читаем описание, убеждаемся

Screenshot 2021-11-17 at 02.54.34.png

Но необходимо делать поправку на то, что здесь используется intel синтаксис, то есть у нас порядок аргументов будет другой


Что такое эффективный адрес?

У нас есть сегмент данных (.data), в нем определен какой-то массив на 100 машинных слов

В регистре %ecx лежит какой-то индекс, мы хотим обратиться к соответствующему элементу массива и положить туда значение из регистра %eax

Строка 2: кладем из регистра %eax в память по адресу (array + %ecx * 4)

Screenshot 2021-11-17 at 03.01.08.png

Вспоминаем полную форму адресации: у нас есть непосредственно заданное смещение immediate

Процессор в ходе выполнения такой инструкции вычисляет адрес в памяти, равный непосредственно заданному смещению immediate + reg1 + reg2 * factor

factor \in {1, 2, 4, 8}

Screenshot 2021-11-17 at 03.05.34.png