Как найти эффективный адрес

Адреса памяти: физические, виртуальные, логические, линейные, эффективные, гостевые

Время на прочтение
6 мин

Количество просмотров 102K

Мне периодически приходится объяснять разным людям некоторые аспекты архитектуры Intel® IA-32, в том числе замысловатость системы адресации данных в памяти, которая, похоже, реализовала почти все когда-то придуманные идеи. Я решил оформить развёрнутый ответ в этой статье. Надеюсь, что он будет полезен ещё кому-нибудь.
При исполнении машинных инструкций считываются и записываются данные, которые могут находиться в нескольких местах: в регистрах самого процессора, в виде констант, закодированных в инструкции, а также в оперативной памяти. Если данные находятся в памяти, то их положение определяется некоторым числом — адресом. По ряду причин, которые, я надеюсь, станут понятными в процессе чтения этой статьи, исходный адрес, закодированный в инструкции, проходит через несколько преобразований.

На рисунке — сегментация и страничное преобразование адреса, как они выглядели 27 лет назад. Иллюстрация из Intel 80386 Programmers’s Reference Manual 1986 года. Забавно, что в описании рисунка есть аж две опечатки: «80306 Addressing Machanism». В наше время адрес подвергается более сложным преобразованиям, а иллюстрации больше не делают в псевдографике.

Начнём немного с конца — с цели всей цепочки преобразований.

Физический адрес

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

Конечный результат?!

На самом деле, легко понять, что это ещё не конец. В платформе, которая должна обработать запрос данных от процессора, может быть несколько чипов DRAM, имеющих собственную структуру разбиения на блоки, а также различные периферийные устройства, отображённые на общее пространство физической памяти. Дальнейший путь транзакции с некоторым физическим адресом будет зависеть от конфигурации нескольких декодеров, находящихся на её пути внутри устройств платформы.

Эффективный адрес

Эффективный адрес — это начало пути. Он задаётся в аргументах индивидуальной машинной инструкции, и вычисляется из значений регистров, смещений и масштабирующих коэффициентов, заданных в ней явно или неявно.

Например, для инструкции (ассемблер в AT&T-нотации)

addl %eax, 0x11(%ebp, %edx, 8)

эффективный адрес операнда-назначения будет вычислен по формуле:

eff_addr = EBP + EDX * 8 + 0x11

Логический адрес

Без знания номера и параметров сегмента, в котором указан эффективный адрес, последний бесполезен. Сам сегмент выбирается ещё одним числом, именуемым селектором. Пара чисел, записываемая как selector:offset, получила имя логический адрес. Так как активные селекторы хранятся в группе специальных регистров, чаще всего вместо первого числа в паре записывается имя регистра, например, ds:0x11223344.

Здесь обычно у тех, кто столкнулся с этими понятиями впервые, голова начинает идти кругом. Несколько упростить (или усложнить) ситуацию помогает тот факт, что почти всегда выбор селектора (и связанного с ним сегмента) делается исходя из «смысла» доступа. По умолчанию, если в кодировке машинной инструкции не сказано иного, для получения адресов кода используются логические адреса с селектором CS, для данных — с DS, для стека — с SS.

Линейный адрес

Эффективный адрес — это смещение от начала сегмента — его базы. Если сложить базу и эффективный адрес, то получим число, называемое линейным адресом:

lin_addr = segment.base + eff_addr

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

Реальный режим

Описанное выше верно при включенной сегментации. В 16-битном реальном режиме смысл селекторов другой, они хранят только базу, а преобразование не осуществляет сегментных проверок. Фактически, обозначения CS, DS, FS, GS, ES, SS имеют совершенно разный смысл в этих двух режимах, что добавляет путаницы.

Сегментация была модной на некотором этапе развития вычислительной техники. В настоящее она почти всюду была заменена другими механизмами, и используется только для специфических задач. Так, в режиме IA-32e (64-битном) только два сегмента могут иметь ненулевую базу. Для остальных четырёх в этом режиме всегда линейный адрес == эффективный.

Что такое виртуальный адрес?

В литературе и в документации других архитектур встречается ещё один термин — виртуальный адрес. Он не используется в документации Intel на IA-32, однако встречается, например, в описании Intel® Itanium, в котором сегментация не используется. Можно смело считать, что для IA-32 виртуальный == линейный.
В советской литературе по вычислительной технике этот вид адресов также именовался математическим.

Страничное преобразование

Следующее после сегментации преобразование адресов: линейный → физический — имеет множество вариаций в своём алгоритме, в зависимости от того, в каком режиме (32-битном, PAE или 64-битном) находится процессор.

Что влияет на paging

Примечательно, сколько различных бит из разных системных регистров процессора влияют на процесс страничного преобразования в настоящее время. Я просмотрел свежую сентябрьскую редакцию Intel SDM [1], и вот полный список: CR0.WP, CR0.PG, CR4.PSE, CR4.PAE, CR4.PGE, CR4.PCIDE, CR4.SMEP, CR4.SMAP, IA32_EFER.LME, IA32_EFER.NXE, EFLAGS.AC.

Однако общая идея всегда одна и та же: линейный адрес разбивается на несколько частей, каждая из которых служит индексом в одной из системных таблиц, хранящихся в памяти. Записи в таблицах — это адреса начала таблицы следующего уровня или, для последнего уровня — искомая информация о физическом адресе страницы в памяти и её свойствах. Самые младшие биты не преобразуются, а используются для адресации внутри найденной страницы. Например, для режима PAE с размером страниц 4 кбайт преобразование выглядит так:

В разных режимах процессора различается число и ёмкость этих таблиц. Преобразование может завершиться неудачей, если очередная таблица не содержит валидных данных, или права доступа, хранящиеся в последней из них, запрещают доступ к странице; например, при записи в регионы, помеченные как «только для чтения», или попытке чтения памяти ядра из непривилегированного процесса.

Гостевой физический

До введения возможностей аппаратной виртуализации в процессорах Intel страничное преобразование было последним в цепочке. Когда же на одной системе работают несколько виртуальных машин, то физические адреса, получаемые в каждой из них, приходится транслировать ещё один раз. Это можно делать программным образом, или же аппаратно, если процессор поддерживает функциональность EPT (англ. Extended Page Table). Адрес, раньше называвшийся физическим, был переименован в гостевой физический для того, чтобы отличать его от настоящего физического. Они связаны с помощью EPT-преобразования. Алгоритм последнего схож с ранее описанным страничным преобразованием: набор связанных таблиц с общим корнем, последний уровень которых определяет, существует ли физическая страница для указанной гостевой физической.

Полная картина

Я попытался собрать все преобразования адреса в одну иллюстрацию. В ней преобразования обозначены стрелками, типы адресов обведены в рамки.

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

Заключение

Эволюция, что в природе, что в технике — странная вещь. Она порождает неожиданные структуры, необъяснимые с точки зрения рационального проектирования. Её творения полны атавизмов, правила их поведения иногда почти полностью состоят из исключений. Для того, чтобы понять работу такой системы, часто требуется прокрутить её эволюцию с самого начала, и под нагромождениями всех слоёв найти истину в виде принципа: «ничего не выбрасывать». Я склонен считать архитектуру IA-32 замечательным примером эволюционного развития.

P.S. Всё как у всех

Вскоре после завершения написания этой статьи я натолкнулся на презентацию об архитектуре IBM System z, которая примечательна в том числе своей долгой и интересной историей поддержки виртуализации. В этом документе нашлось перечисление всех типов адресов памяти, используемых в System z:

  1. Virtual: Translated by dynamic address translation (DAT) to real addresses
  2. Real: Translated to absolute addresses using the prefix register
  3. Absolute: After applying the prefix register
  4. Logical: The address seen by the program (this can either be a virtual or a real address)
  5. Physical: translated to absolute addresses by the Config Array

Как можно заметить, их тоже пять.

Спасибо за внимание!

Литература

  1. Intel Corporation. Intel® 64 and IA-32 Architectures Software Developer’s Manual. Volumes 1–3, 2014. www.intel.com/content/www/us/en/processors/architectures-software-developer-manuals.html

В большинстве вычислительных систем эффективным адресом называется адрес, по которому с точки зрения программиста происходит обращение к памяти; численно он совпадает с виртуальным адресом, причём последний термин используется значительно чаще. Однако в случае архитектуры IA-32 ситуация несколько сложнее. Здесь эффективным адресом называется смещение, то есть один из двух компонентов логического адреса. Другой компонент — селектор сегмента — в состав эффективного адреса не входит и автоматически учитывается процессором при преобразовании логического в линейный адрес и далее в физический адрес. Таким образом, технически эффективный адрес является лишь одним из компонентов адреса, по которому происходит обращение к памяти с точки зрения программы. Однако во всех популярных операционных системах для платформы IA-32, включая Windows и Linux, механизм сегментации используется в минимально необходимой степени, и программы работают в плоском адресном пространстве, манипулируя лишь смещениями, но не селекторами сегментов. В результате можно считать, что эффективный и виртуальный адреса являются эквивалентными (например, говоря о передаче адресов при системных вызовах, документация Microsoft использует термин «виртуальный адрес», однако технически передаётся именно смещение, т.е. значение эффективного адреса, а не полный логический адрес).

Эффективный адрес в общем случае является суммой базового адреса, находящегося в базовом регистре, индекса из индексного регистра и отклонения (displacement), являющегося константой, заданной в команде, например:

mov  ax, 1234h [bx+si]    ; Загрузка слова по эффективному адресу 1234h + BX + SI

В этом примере 1234h является отклонением, регистр BX содержит базовый адрес, а SI — индекс.

Любой из компонентов эффективного адреса может отсутствовать, однако хотя бы один из них должен быть указан. При 16-разрядной адресации в качестве базового регистра могут использоваться только BX и BP, а в качестве индексного — только SI и DI. Отклонение имеет длину 8 или 16 бит и рассматривается как число со знаком. Таким образом, возможны восемь комбинаций регистров, не считая прямой адресации, при которой регистры при вычислении эффективного адреса не используются, и его значение равно отклонению. Если в качестве базового задан регистр BP, то операнд по умолчанию находится в сегменте стека (совместно с эффективным адресом используется сегментный регистр SS), а если базовый регистр не задан или им является BX, то по умолчанию операнд находится в сегменте данных (используется сегментный регистр DS). В любом случае используемый сегмент может быть переопределён с помощью префикса замены сегмента.

При 32-разрядной адресации эффективный адрес также является суммой базового адреса, индекса и отклонения, однако в роли базового регистра может выступать любой регистр общего назначения, а в роли индексного — любой, кроме ESP, причём и базовым, и индексным может быть один и тот же регистр. Кроме того, значение индекса может масштабироваться (автоматически умножаться на 2, 4 или 8), что облегчает адресацию в массивах с элементами указанных размеров. Отклонение является 8- или 32-разрядной величиной со знаком. Примеры такой адресации:

mov   eax, [1234h]          ; Загрузка двойного слова из ячейки с эффективным адресом 1234h
mov   eax, 1234h [ecx]      ; Загрузка из ячейки с эффективным адресом 1234h + ECX
mov   eax, [ebx+4*edx]      ; Загрузка из ячейки с эффективным адресом EBX + 4*EDX

При 64-разрядной адресации эффективный адрес формируется в целом аналогично, однако есть и некоторые особенности:

  • используются не 32-, а 64-разрядные регистры;
  • с помощью префикса REX при формировании эффективного адреса можно в роли базового и индексного использовать новые регистры R8-R15;
  • отклонение является 8- или 32-разрядной величиной, рассматриваемой как число со знаком. 64-разрядного отклонения не предусмотрено;
  • отсутствует возможность адресации памяти только с помощью отклонения (обязательно наличие базового и/или индексного регистра). Исключением является команда MOV, у которой имеются формы, использующие прямую 64-разрядную адресацию памяти;
  • появилась возможность адресации относительно указателя инструкции RIP. В этом случае эффективный адрес равен сумме 64-разрядного адреса следующей команды и 32-разрядного смещения, рассматриваемого как число со знаком;
  • сегментные регистры FS и GS могут использоваться в качестве дополнительных базовых регистров (подробнее об этом написано в разделе Управление памятью в режиме IA-32e).

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

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

2.
В плоской модели памяти приложению для
всех целей выделяется единственный
сегмент. В этой модели приложение
оперирует линейными адресами.

Логический
адрес состоит

из селектора сегмента Seg и эффективного
адреса
,
называемого также смещением (offset).
Логический адрес обозначается в форме
Seg:Offset. Селектор сегмента хранится в
старших 14 битах сегментного регистра
(CS, DS, ES, SS, FS или GS), участвующего в адресации
конкретного элемента памяти.Преобразование
логического адреса в физический для
32-битных процессоров.

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

Блок
страничной трансляции адресов позволяет
использовать разрядность физического
адреса, отличную от разрядности линейного
адреса. В процессорах различных моделей
соотношения разрядностей менялись:

1.
В 386SX при 32-битном линейном адресе
физический был 24-битным (до 16 Мбайт
физически адресуемой памяти).

2.
В большинстве 32-битных процессоров до
6-го поколения использовался 32-битный
физический адрес (до 4 Гбайт физически
адресуемой памяти). Формирование адреса
памяти процессоров с 64-битным расширением
рисунок.

14) Страничная трансляция адресов и виртуальная память

СТА.Механизм
сегментации обеспечивает превосходную
защиту, но он не очень удобен для
реализации виртуальной памяти (подкачки).
В дескрипторе сегмента есть бит
присутствия, по нему процессор определяет,
находится ли данный сегмент в физической
памяти или он находится на внешнем
запоминающем устройстве (на винчестере).
В последнем случае генерируется
исключение #11, обработчик которого может
подгрузить сегмент в память. Неудобство
заключается в том, что различные сегменты
могут иметь различную длину. Этого можно
избежать, если механизм подкачки
реализовывать на основе страничного
преобразования. Особенностью этого
преобразования является то, что процессор
в этом случае оперирует с блоками
физической памяти равной длины (4Кбайт)
— страницами. Страницы не имеют
непосредственного отношения к логической
структуре программы.Страничное
преобразование действует только в
защищенном режиме и включается установкой
в 1 бита PG в регистре CR0.

Под виртуализацией
памяти понимается метод автоматического
управления иерархической памятью. По
своей сути виртуализация памяти
представляет способ аппаратной и
программной реализации концепции
иерархической памяти. В рамках идеи
виртуализации памяти ОП рассматривается
как линейное пространство N адресов,
называемое физическим пространством
(ФП) памяти. Для задач, где требуется
более чем N ячеек, предоставляется
значительно большее пространство
адресов (обычно равное общей емкости
всех видов памяти), называемое виртуальным
пространством (ВП).

Страничная
организация виртуальной памяти

Страничная
организация памяти служит целям
преобразования виртуальных адресов в
физические. Программа разбивается на
части равной величины, называемые
страницами. Размер страницы обычно
выбирают в пределах 4 – 8 Кбайт (должен
быть кратен емкости одного сектора
магнитного диска). Виртуальное и
физическое адресные пространства
разбиваются на блоки размером в страницу.
Блок ОП, соответствующий странице, часто
называют страничным кадром или фреймом
(page frame). Страницам виртуальной и физической
памяти присваивают номера.

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

  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #
  • #

Адреса памяти: физические, виртуальные, логические, линейные, эффективные, гостевые

Мне периодически приходится объяснять разным людям некоторые аспекты архитектуры Intel® IA-32, в том числе замысловатость системы адресации данных в памяти, которая, похоже, реализовала почти все когда-то придуманные идеи. Я решил оформить развёрнутый ответ в этой статье. Надеюсь, что он будет полезен ещё кому-нибудь.
При исполнении машинных инструкций считываются и записываются данные, которые могут находиться в нескольких местах: в регистрах самого процессора, в виде констант, закодированных в инструкции, а также в оперативной памяти. Если данные находятся в памяти, то их положение определяется некоторым числом — адресом. По ряду причин, которые, я надеюсь, станут понятными в процессе чтения этой статьи, исходный адрес, закодированный в инструкции, проходит через несколько преобразований.

На рисунке — сегментация и страничное преобразование адреса, как они выглядели 27 лет назад. Иллюстрация из Intel 80386 Programmers’s Reference Manual 1986 года. Забавно, что в описании рисунка есть аж две опечатки: «80306 Addressing Machanism». В наше время адрес подвергается более сложным преобразованиям, а иллюстрации больше не делают в псевдографике.

Начнём немного с конца — с цели всей цепочки преобразований.

Физический адрес

Эффективный адрес

Эффективный адрес — это начало пути. Он задаётся в аргументах индивидуальной машинной инструкции, и вычисляется из значений регистров, смещений и масштабирующих коэффициентов, заданных в ней явно или неявно.

Например, для инструкции (ассемблер в AT&T-нотации)

addl %eax, 0x11(%ebp, %edx, 8)

эффективный адрес операнда-назначения будет вычислен по формуле:

eff_addr = EBP + EDX * 8 + 0x11

Логический адрес

Без знания номера и параметров сегмента, в котором указан эффективный адрес, последний бесполезен. Сам сегмент выбирается ещё одним числом, именуемым селектором. Пара чисел, записываемая как selector:offset , получила имя логический адрес. Так как активные селекторы хранятся в группе специальных регистров, чаще всего вместо первого числа в паре записывается имя регистра, например, ds:0x11223344.

Здесь обычно у тех, кто столкнулся с этими понятиями впервые, голова начинает идти кругом. Несколько упростить (или усложнить) ситуацию помогает тот факт, что почти всегда выбор селектора (и связанного с ним сегмента) делается исходя из «смысла» доступа. По умолчанию, если в кодировке машинной инструкции не сказано иного, для получения адресов кода используются логические адреса с селектором CS, для данных — с DS, для стека — с SS.

Линейный адрес

Эффективный адрес — это смещение от начала сегмента — его базы. Если сложить базу и эффективный адрес, то получим число, называемое линейным адресом:

lin_addr = segment.base + eff_addr

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

Сегментация была модной на некотором этапе развития вычислительной техники. В настоящее она почти всюду была заменена другими механизмами, и используется только для специфических задач. Так, в режиме IA-32e (64-битном) только два сегмента могут иметь ненулевую базу. Для остальных четырёх в этом режиме всегда линейный адрес == эффективный.

Что такое виртуальный адрес?

В литературе и в документации других архитектур встречается ещё один термин — виртуальный адрес. Он не используется в документации Intel на IA-32, однако встречается, например, в описании Intel® Itanium, в котором сегментация не используется. Можно смело считать, что для IA-32 виртуальный == линейный.
В советской литературе по вычислительной технике этот вид адресов также именовался математическим.

Страничное преобразование

Однако общая идея всегда одна и та же: линейный адрес разбивается на несколько частей, каждая из которых служит индексом в одной из системных таблиц, хранящихся в памяти. Записи в таблицах — это адреса начала таблицы следующего уровня или, для последнего уровня — искомая информация о физическом адресе страницы в памяти и её свойствах. Самые младшие биты не преобразуются, а используются для адресации внутри найденной страницы. Например, для режима PAE с размером страниц 4 кбайт преобразование выглядит так:

В разных режимах процессора различается число и ёмкость этих таблиц. Преобразование может завершиться неудачей, если очередная таблица не содержит валидных данных, или права доступа, хранящиеся в последней из них, запрещают доступ к странице; например, при записи в регионы, помеченные как «только для чтения», или попытке чтения памяти ядра из непривилегированного процесса.

Гостевой физический

До введения возможностей аппаратной виртуализации в процессорах Intel страничное преобразование было последним в цепочке. Когда же на одной системе работают несколько виртуальных машин, то физические адреса, получаемые в каждой из них, приходится транслировать ещё один раз. Это можно делать программным образом, или же аппаратно, если процессор поддерживает функциональность EPT (англ. Extended Page Table). Адрес, раньше называвшийся физическим, был переименован в гостевой физический для того, чтобы отличать его от настоящего физического. Они связаны с помощью EPT-преобразования. Алгоритм последнего схож с ранее описанным страничным преобразованием: набор связанных таблиц с общим корнем, последний уровень которых определяет, существует ли физическая страница для указанной гостевой физической.

Полная картина

Я попытался собрать все преобразования адреса в одну иллюстрацию. В ней преобразования обозначены стрелками, типы адресов обведены в рамки.

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

Как определяется физический адрес переменной

страницы: 1 2 3 4

Основные понятия и применение динамически распределяемой памяти. Списочные структуры данных и принципы работы с ними.

Содержание

  • Содержание
  • Статически выделяемая память
  • Адреса
  • Указатели
    • Описание указателей
    • Определение адреса
    • Разыменование

    Статически выделяемая память

    Для того, чтобы лучше понять специфику динамически выделяемой памяти, рассмотрим сначала её «антипод» — память, распределяемую статически.

    Такое выделение памяти используется всякий раз при объявлении «обычных» переменных в разделе var . Каждая переменная обладает двумя атрибутами: именем и описанием .

    Описание переменной нужно для того, чтобы компилятор знал, сколько ячеек памяти необходимо выделить для её хранения. Память под статическую переменную выделяется один раз (до начала работы программы), и затем до конца работы выделенная область памяти считается «занятой» — никакая другая информация не может быть записана в эту ячейку.

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

    Адреса

    Имя переменной является её своеобразным (буквенным) адресом . Однако у любой переменной есть также и обычный (цифровой или физический) адрес : номер ячейки, выделенной под эту переменную.

    При страничной организации памяти адреса являются составными и состоят из номера сегмента памяти и смещения ячейки относительно начала этого сегмента.

    Лучшая иллюстрация страничной организации памяти компьютера — это страничная организация любой печатной книги. Для того, чтобы найти нужную строчку, нет необходимости задавать её номер, считая от начала текста. Вместо этого можно задать сначала номер страницы ( = сегмент) и только затем номер строки, считая от начала этой страницы ( = смещение).

    Для обращения к статически заданной переменной можно использовать как её имя , объявленное в разделе var , так и её физический адрес .

    Например, « адрес » одной и той же географической точки можно записать по-разному: «49°47′ северной широты и 86°36′ восточной долготы» или просто «вершина пика Белуха Восточная 1 ».

    Указатели

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

    Описание указателей

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

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

    Операции с указателями

    Определение адреса

    Физический адрес любой переменной можно узнать при помощи стандартной функции Addr (<имя_переменной>) : <указатель> или унарной операции @ <имя_переменной> .

    Результат функции Addr () совместим с указателями любых типов:

    Разыменование

    Для того, чтобы воспользоваться значением, хранящимся по некоторому адресу , необходимо его оттуда «извлечь». Унарная операция ^ называется разыменованием и записывается по следующему шаблону:

    Результатом операции ^ является значение, хранящееся по указанному адресу . Тип этого значения будет определяться типом ( типизированного ) указателя . К нетипизированным указателям операцию разыменования применять нельзя.

    Из–за вольностей, допускаемых процедурой Addr () , при разыменовании порой могут возникнуть забавные ситуации. Например, в результате выполнения такой вот программы:

    на экран будет выведено 32896 , что в двоичной системе счисления выглядит как 10000000.10000000 (точкой помечена граница двух байтов). Иными словами, коды двух первых букв оказались слитыми в значение типа Word .

    Замечание: Операции @ и ^ являются взаимно обратными, то есть для любой переменной a и для любого типизированного указателя p верны следующие равенства:

    Где и как хранится адрес переменной?

    Господа, занимаюсь по Java Rush, и там присутствует такая фраза: «Адресом переменной считается адрес первой ячейки выделенного под нее блока памяти.» скрин
    Т. е. если, например, под переменную int x выделяется 4 байта (ячейки памяти), то адрес этой переменной будет хранится в первом байте? Но ведь все 4 байта отводятся строго под число. Тогда что же получается, под переменную x на самом деле выделяется 5 байт, чтобы в первом байте хранить её адрес?
    Link на саму лекцию.
    Или как с объектом класса String. Переменная типа String хранит в себе адрес первой ячейки блока памяти, выделенного под сам объект этого класса. Но ведь перменная с адресом объекта должна в себе же хранить и свой адрес тоже.введите сюда описание изображенияНапример переменная str хранит адрес первой ячеки выделенного под объект типа String блока памяти: G13. Но получается что в первой ячейке самой переменной str должен хранится её собственный адрес: B13.
    Объясните подробно новичку этот момент. Пожалуйста.

suppose you have this instruction in assembly Nasm

MOV EAX, [label1] ; label1 is at location 0x00D5A360

how do you calculate the effective address is it ^ the location above.

I know for fact that the addressing mode is Direct.

Cœur's user avatar

Cœur

36.8k25 gold badges192 silver badges262 bronze badges

asked Oct 18, 2011 at 0:33

Shawn ricshawnawic's user avatar

2

In nasm label refers to the address of label while [label] retrieves the value stored there. So you can do:

    mov eax, label1      ; eax <- 0x00D5A360

Or use the versatile lea (load effective address):

    lea eax, [label1]    ; eax <- 0x00D5A360

Or are you asking HOW the assembler determines the effective address? Because that is handled in combination by the assembler, optionally a linker and the loader. Usually your code will compile into an intermediate object format with relocations and the linker or loader will handle calculating the effective address of label1 for you.

answered Oct 18, 2011 at 5:35

user786653's user avatar

3

From the «Intel 64 and IA-32 Architectures Software Developer’s Manual: Volume 2»:

LEA r16, m ; Store effective address for m in register r16.
LEA r32, m ; Store effective address for m in register r32.
LEA r64, m ; Store effective address for m in register r64.

Computes the effective address of the second operand (the source operand) and stores it in the first operand (destination operand). The source operand is a memory address (offset part) specified with one of the processor’s addressing modes; the destination operand is a general-purpose register.

Examples:

; indirect addressing mode
MOV EBX, label1   ; copy the address of label1 to EBX
MOV [EBX], 100    ; store 100 at the location pointed to by EBX

; using LEA
LEA EBX, [label1] ; stores the effective address of label1 in EBX
MOV [EBX], 100    ; store 100 at the location pointed to by EBX

The difference between the two is that LEA computes the effective address at runtime, whereas the MOV version resolves the effective address at assembly time.

answered Oct 18, 2011 at 6:27

Jordan Pickwell's user avatar

1

Понравилась статья? Поделить с друзьями:

Не пропустите также:

  • Как найти михаила мишустина
  • Как составить претензию на неустойку по договору
  • Как исправить ошибку консоль разработчика в tlauncher
  • Как найти координатный вектор образующий с вектором
  • Как найти напряжение эдс в цепи

  • 0 0 голоса
    Рейтинг статьи
    Подписаться
    Уведомить о
    guest

    0 комментариев
    Старые
    Новые Популярные
    Межтекстовые Отзывы
    Посмотреть все комментарии