Вопрос

Есть что -то, что я не могу переварить. Я изучаю какого -то ассемблера, и сейчас я нахожусь в главе с обращением. Я понимаю концепцию кронштейнов для деревенского приземления, но каким -то образом, когда я вижу его использование, я просто не могу впитать это. Быть немного точным здесь, где началась моя путаница:

mov al, [L1]

Здесь я полагаю, что L1 в качестве примера случая - это своего рода макрос, который впоследствии заменяется реальным адресом в машинном коде, верно?

Итак, что это делает al Зарегистрируйтесь (потому что вы вряд ли изменили физический адрес) и изменять значение на то, что хранится в L1.

Если до сих пор все в порядке:

mov [L1], al

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

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

И последнее, NASM добавляет кучу 0xAA55 Под моим кодом (эта последовательность должна закончить программу, верно?), Почему она там много раз?

Это было полезно?

Решение

L1 является обычно/, вероятно этикетка, связан с одним конкретным адресом в памяти. Программист определяет различные этикетки для его/ее удобства, и такие этикетки используются для символического представления определенного места в памяти (L1 - паршивое имя; этикетки обычно указывают на основную цель местоположения: скажем, Pingcounter, Errormessage, Login и тому подобное).

Метка для 1 байта статического хранилища - это то, как будет реализовать компилятор C char L1; в глобальном масштабе.


В синтаксисе NASM, mov edi, L1 собирается в mov eax, imm32 форма mov, т.е. адрес метки станет 32-разрядным немедленным в машинном коде. (Ассемблер не знает окончательного числового значения, но линкер делает.) Остерегайтесь, что в синтаксисе MASM это будет нагрузка, и вам понадобится mov edi, OFFSET L1 Чтобы получить адрес ярлыка в качестве немедленного.

Но mov al, [L1] Собирается в другую инструкцию, с 32-разрядным адресом, встроенным в машинный код в качестве адреса, который должен быть привязан. Эта инструкция загружается 1 байт от адреса L1 и помещает ее в AL.

На языке сборки этот режим непрямой адресации обозначается квадратным кронштейном источника или операнда назначения данной инструкции. (Но не оба: x86 поддерживает только один явный операнд памяти на инструкцию.)

mov al, [L1]

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

  mov [L1], al

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


При условии, что вы понимаете, что следующая информация является неполной и несколько устаревшей в отношении новых процессоров в семье x86, это учебник на архитектуре 8086 Вероятно, очень полезен, чтобы начать с языка собрания для семьи x86.
Преимущество начала с этой «древности процессора» (на самом деле, на самом деле используется), заключается в том, что фундаментальные концепции находятся там, не обремененные более новыми наборами регистров, причудливых режимов обращения, режимов работы и других концепций. Большие размеры, функции и режимы более новых процессоров просто вводят комбинаторный взрыв вариантов, все (большинство?) Из них полезны на своем пути, но по существу не относящиеся к инициации.

Другие советы

Трудно следовать вашему вопросу, но я постараюсь помочь.

В сборке символ - это просто имя для адреса. В вашем источнике сборки L1 является символом, определяемым в другом месте, который ассемблер решит как смещение памяти.

При дреферинге (с использованием [] обозначения) вы можете определить регистр (как в «voal, [esi]») или адреса (как в «mov al, [l1]»). Оба утверждения делают одно и то же, единственное отличие - это то, откуда поступает адрес.

Я рекомендую скачать Документация CPU Intel и просматривать ссылку на инструкцию. Если вы не хотите быть перегруженным, начните читать с более старого процессора X86 (скажем, 486 или старше), эта документация не совсем дружелюбна, но очень полезно иметь под рукой.

Я не знаю специфики NASM, я выучил сборку 15 лет назад с Turbo Assembler, и эти знания все еще полезны сегодня :)

Кроме того, могу я предложить вам попробовать Googling для «Учебного пособия x86 Assembly», вы найдете много соответствующей документации, которая может быть полезна для вас.

О, и, в последнее время, NASM добавляет кучу 0xAA55 под моим кодом (эта последовательность должна закончить программу верно?), Почему она там много раз? Большое спасибо за то, что прочитали его здесь ..

Я уверен, что это применимо, только если вы создаете загрузчик. Это «подпись загрузки». Скажем, вы пишете этот код в дискету (ваш созданный машинный код также ровно 512 байтов?), Ну, если вы хотите запустить компьютер с этим кодом загрузчика, BIOS будет смотреть на дискету и определить, является ли это фактическим загрузчиком. Для этого он будет рассмотреть на последние два байта первого сектора дискету, который должен быть 0xAA55 Чтобы указать, что он загружается. (Кроме того, это работает так же, если вы загружаетесь с жесткой или большим приводом, или что-то еще. Немного отличается для компакт-дисков, потому что у них 4096 байтовых секторов)

В вашем исходном коде это как последняя строка что -то вроде $(times.. db 0xAA55 или что-то вроде того? Если вы не намереваясь сделать загрузчик, вы можете эффективно удалить эту линию.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top