какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

Команда JMP

Синтаксис команды JMP такой:

МЕТКОЙ может быть один из следующих:

Безусловный переход в Ассемблере выполняется всегда и в любом случае, если в исходном коде имеется инструкция JMP.

Никакие флаги при выполнении этой инструкции не изменяются.

Что такое безусловный переход

Что такое метка в Ассемблере

Теперь немного поговорим о том, что такое метка в Ассемблере.

Пример метки в Ассемблере:

Для чего нужны метки?

Для того, чтобы управлять ходом выполнения программы.

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

Тогда каждый участок кода обозначается своей меткой. И таким образом вы будете иметь возможность пропустить какой-то участок кода и сразу перейти к другому участку.

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

В языках высокого уровня подобные действия называются ветвлением, и реализуются с помощью соответствующих конструкций языка (таких как if. then. else или case в Паскале).

Пример безусловного перехода

Сначала давайте подумаем, зачем нужен безусловный переход.

Логичный вопрос: если мы всегда и во всех случаях пропускаем участок кода, то зачем нам тогда вообще этот участок?

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

Пример первый: не забывайте, что вы можете переходить по программе не только вниз, но и вверх. Так что при первом проходе участок кода можно пропустить, но, возможно, его придётся выполнить в зависимости от условий, которые появятся дальше в программе. Как-нибудь так:

Здесь при первом проходе программы мы пропускаем участок кода 1 и сразу переходим к метке Label_2 (то есть ко второму участку). Но во втором участке мы возвращаемся к участку 1 (к метке Label_1) и выполняем его.

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

Обратите внимание, что инструкция JMP закомментирована, то есть не выполняется. Так что пока вы отлаживаете свою программу, участок кода для отладки выполняется.

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

А почему бы просто не убрать отладочный код?

Можно, конечно, и убрать. Но вы уверены, что он вам больше не пригодится?

В конце как обычно расскажу, почему эта команда ассемблера называется JMP. Это сокращение от английского слова JUMP, которое можно перевести как “прыжок, переход”.

Источник

Виртуальный мир Intel. Практика

В данной статье я хочу рассмотреть практические аспекты создания простого гипервизора на основе технологии аппаратной виртуализации Intel VMX.

Аппаратная виртуализация достаточно узкоспециализированная область системного программирования и не имеет большого комьюнити, в России уж точно. Я надеюсь, что материал статьи поможет тем, кто захочет открыть для себя аппаратную виртуализацию и те возможности которые она предоставляет. Как было сказано в начале, я хочу рассмотреть именно практический аспект без погружения в теорию, поэтому предполагается что читатель знаком с архитектурой x86-64 и имеет хотя бы общее представление о механизмах VMX. Исходники к статье.

Описание работы загрузчика

Для того чтобы гипервизор запускался при старте PC я выбрал самый простой путь, а именно записал свой загрузчик в MBR сектор диска на который установлена гостевая ОС. Так же нужно было где-то на диске разместить код гипервизора. В моем случае, оригинальная MBR считывает bootloader начиная с 2048 сектора, что дает условно свободную область для записи в (2047 * 512) Кб. Этого более чем достаточно для размещения всех компонентов гипервизора.

Ниже приведена схема размещения гипервизора на диске, все значения заданы в секторах.

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

Процесс загрузки происходит следующим образом:

Более подробно о котором можно почитать тут.

Описание работы гипервизора

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

Следует обратить внимание на то что поле limit дескрипторного кэша для сегментных регистров DS и ES равно 0xFFFFFFFF. Это пример использования unreal mode — особенности процессора x86 позволяющей обходить лимит сегментов в реальном режиме. Подробней об этом можно почитать тут.

Находясь в vmx not-root режиме гостевая ОС может столкнутся с ситуацией, когда необходимо вернуть управление хосту в режим vmx root. В таком случае происходит VM exit во время которого сохраняется текущее состояние vmx non-root и загружается vmx-root. Инициализация vmx-root выполняется функцией InitHostStateArea(), которая устанавливает следующее значение регистров:

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

На следующем изображении приведена модель гостевого физического адресного пространства:

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

Итак, что мы тут видим:

После того как завершено создание гостевого адресного пространства, можно перейти к настройкам VM Execution control field (функция InitExecutionControlFields()). Это довольно большой набор опций, которые позволяют задать условия работы гостевой ОС в режиме vmx not-root. Можно, к примеру, отслеживать обращения к портам ввода вывода или контролировать изменение MSR регистров. Но нашем случае я использую только возможность контролировать установку определенных бит в регистре CR0. Дело в том, что 30(CD) и 29(NW) биты общие как для vmx non-root так и для vmx root режимов и если гостевая ОС установит эти биты в 1 это негативно скажется на производительности.

Процесс настройки гипервизора почти завершен, осталось только установить контроль за переходом в гостевой режим vmx non-root и возвращением в режим хоста vmx root. Настройки задаются в функциями:

InitVMEntryControl() настройки для перехода в vmx non-root:

Итоги

Написанный в качестве примера к статье гипервизор вполне способен поддерживать стабильную работу гостевой ОС, хотя конечно и не является законченным решением. Не используется Intel VT-d, реализована поддержка только одного логического процессора, нет контроля за прерываниями и работой периферийных устройств. В общем я не использовал почти ничего из богатого набора средств, которые предоставляет Intel для аппаратной виртуализации. Впрочем, если сообщество заинтересуется я продолжу писать про Intel VMX, тем более что написать есть о чем.

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

Источник

MS-DOS и TASM 2.0. Часть 10. Команды ассемблера.

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

Команды ассемблера и команды процессора.

Стоит пояснить, что если к вопросу подойти формально строго, то команды процессора и команды ассемблера — это не одно и то же. Ассеммблер — хоть и низкоуровневый язык программирования, но иногда он без спроса программиста «корректирует код под себя». Причём у каждого ассемблера (masm, tasm, fasm) это может быть по-разному. Самый яркий пример — команда ret. В ассемблерном коде мы запишем ret, а реальный ассемблер ассемблирует её как retf или retn 8. Может также изменяться код, добавлением в качестве выравнивания кода команды процессора nop (об этом ниже в статье) и т.п. Чтобы не усложнять суть вопроса, под понятиями команды процессора и команды ассемблера мы будем подразумевать одно и то же.

Команды процессора (команды ассемблера) в большинстве своём работают с аргументами, которые в ассемблере называются операндами. Система машинного кода процессоров Intel содержит более 300 команд (команды процессора, сопроцессора, MMX-расширения, XMM-расширения). С каждым новым процессором их количество растёт. Для того, чтобы профессионально программировать, не надо зубрить и разбирать все команды процессора. При необходимости можно воспользоваться справочником. В процессе чтения статей, вы поймёте, что основная суть знания ассемблера состоит не в доскональном знании всех команд, а в понимании работы системы.

Не следует забывать, что команды процессор видит в виде цифр, которые можно рассматривать как данные. Например, команда NOP занимает один байт и её машинный код — 90h.

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

Основные (т.н. целочисленные) команды ассемблера позволяют написать практически любую программу для операционных систем MS-DOS и Windows. Количество команд ассемблера, которыми вы будете пользоваться будет расти со временем прохождения курса. Для более детального понимания, в последствии можете обратиться к справочнику команд.

Рассмотрим команды ассемблера на практическом примере.

С использованием среды разработки TASMED или любого текстового редактора набираем код. Программа, задаст вопрос на английском языке о половой принадлежности (имеется ввиду ваш биологический пол при рождении). Если вы нажмете m (Man), будет выведено приветствие с мужчиной, если w (Woman), то с женщиной, после этого программа прекратит работу. Если будет нажата любая другая клавиша, то программа предположит, что имеет дело с гоблином, не поверит и будет задавать вам вопросы о половой принадлежности, пока вы не ответите верно.

Источник

Пишем собственную виртуальную машину

В этом руководстве я расскажу, как написать собственную виртуальную машину (VM), способную запускать программы на ассемблере, такие как 2048 (моего друга) или Roguelike (моя). Если вы умеете программировать, но хотите лучше понять, что происходит внутри компьютера и как работают языки программирования, то этот проект для вас. Написание собственной виртуальной машины может показаться немного страшным, но я обещаю, что тема удивительно простая и поучительная.

Окончательный код составляет около 250 строк на C. Достаточно знать лишь основы C или C++, такие как двоичная арифметика. Для сборки и запуска подходит любая Unix-система (включая macOS). Несколько API Unix используются для настройки ввода и отображения консоли, но они не являются существенными для основного кода. (Реализация поддержки Windows приветствуется).

Примечание: эта VM — грамотная программа. То есть вы прямо сейчас уже читаете её исходный код! Каждый фрагмент кода будет показан и подробно объяснён, так что можете быть уверены: ничего не упущено. Окончательный код создан сплетением блоков кода. Репозиторий проекта тут.

1. Оглавление

2. Введение

Что такое виртуальная машина?

Виртуальная машина — это программа, которая действует как компьютер. Она имитирует процессор с несколькими другими аппаратными компонентами, позволяя выполнять арифметику, считывать из памяти и записывать туда, а также взаимодействовать с устройствами ввода-вывода, словно настоящий физический компьютер. Самое главное, VM понимает машинный язык, который вы можете использовать для программирования.

Сколько аппаратного обеспечения имитирует конкретная VM — зависит от её предназначения. Некоторые VM воспроизводят поведение одного конкретного компьютера. У людей больше нет NES, но мы всё ещё можем играть в игры для NES, имитируя аппаратное обеспечение на программном уровне. Эти эмуляторы должны точно воссоздать каждую деталь и каждый основной аппаратный компонент оригинального устройства.

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

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

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

Виртуальная машина Java (JVM) — очень успешный пример. Сама JVM относительно среднего размера, она достаточно мала для понимания программистом. Это позволяет писать код для тысяч разнообразных устройств, включая телефоны. После реализации JVM на новом устройстве любая написанная программа Java, Kotlin или Clojure может работать на нём без изменений. Единственными затратами будут только накладные расходы на саму VM и дальнейшее абстрагирование от машинного уровня. Обычно это довольно хороший компромисс.

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

VM также полезны для безопасной изоляции программ. Одно из применений — сборка мусора. Не существует тривиального способа реализовать автоматическую сборку мусора поверх C или C++, так как программа не может видеть собственный стек или переменные. Однако VM находится «вне» запущенной программы и может наблюдать все ссылки на ячейки памяти в стеке.

Ещё один пример такого поведения демонстрируют смарт-контракты Ethereum. Смарт-контракты — это небольшие программы, которые выполняются каждым узлом валидации в блокчейне. То есть операторы разрешают выполнение на своих машинах любых программ, написанных совершенно незнакомыми людьми, без какой-либо возможности изучить их заранее. Чтобы предотвратить вредоносные действия, они выполняются на VM, не имеющей доступа к файловой системе, сети, диску и т.д. Ethereum — также хороший пример переносимости. Благодаря VM можно писать смарт-контракты без учёта особенностей множества платформ.

3. Архитектура LC-3

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

Наша VM будет симулировать вымышленный компьютер под названием LC-3. Он популярен для обучения студентов ассемблеру. Здесь упрощённый набор команд по сравнению с x86, но сохраняются все основные концепции, которые используются в современных CPU.

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

Память

В компьютере LC-3 есть 65 536 ячеек памяти (2 16 ), каждая из которых содержит 16-разрядное значение. Это означает, что он может хранить всего 128 Кб — намного меньше, чем вы привыкли! В нашей программе эта память хранится в простом массиве:

Регистры

Регистр — это слот для хранения одного значения в CPU. Регистры подобны «верстаку» CPU. Чтобы он мог работать с каким-то фрагментом данных, тот должен находиться в одном из регистров. Но поскольку регистров всего несколько, в любой момент времени можно загрузить только минимальный объём данных. Программы обходят эту проблему, загружая значения из памяти в регистры, вычисляя значения в другие регистры, а затем сохраняя окончательные результаты обратно в память.

В компьютере LC-3 всего 10 регистров, каждый на 16 бит. Большинство из них —общего назначения, но некоторым назначены роли.

Как и память, будем хранить регистры в массиве:

Набор инструкций

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

Каждый опкод представляет собой одну задачу, которую процессор «знает», как выполнить. В LC-3 всего 16 опкодов. Компьютер может вычислить только последовательность этих простых инструкций. Длина каждой инструкции 16 бит, а левые 4 бита хранят код операции. Остальные используются для хранения параметров.

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

Примечание: в архитектуре Intel x86 сотни инструкций, в то время как в других архитектурах, таких как ARM и LC-3, очень мало. Небольшие наборы инструкций называются RISC, а более крупные — CISC. Большие наборы инструкций, как правило, не предоставляют принципиально новых возможностей, но часто упрощают написание ассемблерного кода. Одна инструкция CISC может заменить несколько инструкций RISC. Однако процессоры CISC более сложны и дороги в проектировании и производстве. Это и другие компромиссы не позволяют назвать «оптимальный» дизайн.

Флаги условий

У каждого процессора множество флагов состояния для сигнализации о различных ситуациях. LC-3 использует только три флага условий, которые показывают знак предыдущего вычисления.

Мы закончили настройку аппаратных компонентов нашей виртуальной машины! После добавления стандартных включений (см. по ссылке выше) ваш файл должен выглядеть примерно так:

Здесь указаны ссылки на пронумерованные разделы статьи, откуда берутся соответствующие фрагменты кода. Полный листинг см. в рабочей программе — прим. пер.

4. Примеры на ассемблере

Теперь рассмотрим программу на ассемблере LC-3, чтобы получить представление, что фактически выполняет виртуальная машина. Вам не нужно знать, как программировать на ассемблере, или всё тут понимать. Просто постарайтесь получить общее представление, что происходит. Вот простой «Hello World»:

Как и в C, программа выполняет по одному оператору сверху вниз. Но в отличие от C, здесь нет вложенных областей <> или управляющих структур, таких как if или while ; только простой список операторов. Поэтому его гораздо легче выполнить.

Обратите внимание, что имена некоторых операторов соответствуют опкодам, которые мы определили ранее. Мы знаем, что в инструкциях по 16 бит, но каждая строка выглядит как будто с разным количеством символов. Как возможно такое несоответствие?

Это происходит потому что код, который мы читаем, написан на ассемблере — в удобочитаемой и доступной для записи форме обычным текстом. Инструмент, называемый ассемблером, преобразует каждую строку текста в 16-разрядную двоичную инструкцию, понятную виртуальной машине. Эта двоичная форма, которая по сути представляет собой массив 16-разрядных инструкций, называется машинным кодом и фактически выполняется виртуальной машиной.

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

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

Циклы и условия выполняются с помощью goto-подобной инструкции. Вот еще один пример, который считает до 10.

Примечание: для этого руководства необязательно учиться ассемблеру. Но если вам интересно, можете написать и собрать собственные программы LC-3 с помощью LC-3 Tools.

5. Выполнение программ

Ещё раз, предыдущие примеры просто дают представление, что делает VM. Для написания VM вам не нужно полное понимание ассемблера. Пока вы следуете соответствующей процедуре чтения и исполнения инструкций, любая программа LC-3 будет корректно работать, независимо от её сложности. В теории, VM может запустить даже браузер или операционную систему, как Linux!

Если глубоко задуматься, то это философски замечательная идея. Сами программы могут производить сколь угодно сложные действия, которые мы никогда не ожидали и, возможно, не сможем понять. Но в то же время вся их функциональность ограничивается простым кодом, который мы напишем! Мы одновременно знаем всё и ничего о том, как работает каждая программа. Тьюринг упоминал эту чудесную идею:

«Мнение о том, что машины не могут чем-либо удивить человека, основывается, как я полагаю, на одном заблуждении, которому в особенности подвержены математики и философы. Я имею в виду предположение о том, что коль скоро какой-то факт стал достоянием разума, тотчас же достоянием разума становятся все следствия из этого факта». — Алан М. Тьюринг

Процедура

Вот точное описание процедуры, которую нужно написать:

Начнём изучение этого процесса на примере основного цикла:

6. Реализация инструкций

Теперь ваша задача — сделать правильную реализацию для каждого опкода. Подробная спецификация каждой инструкции содержится в документации проекта. Из спецификации нужно узнать, как работает каждая инструкция, и написать реализацию. Это проще, чем кажется. Здесь я продемонстрирую, как реализовать две из них. Код для остальных можно найти в следующем разделе.

Инструкция ADD берёт два числа, складывает их и сохраняет результат в регистре. Спецификация в документации на стр. 526. Каждая инструкция ADD выглядит следующим образом:

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

Таким образом, мы знаем, где сохранить результат, и знаем первое число для сложения. Осталось только узнать второе число для сложения. Здесь две строки начинают различаться. Обратите внимание, что вверху 5-й бит равен 0, а внизу — 1. Этот бит соответствует или непосредственному режиму, или регистровому режиму. В регистровом режиме второе число хранится в регистре, как и первое. Оно отмечено как SR2 и содержится в битах со второго по нулевой. Биты 3 и 4 не используются. На ассемблере это будет написано так:

В непосредственном режиме вместо добавления содержимого регистра непосредственное значение внедряется в саму инструкцию. Это удобно, потому что программе не нужны дополнительные инструкции для загрузки этого числа в регистр из памяти. Вместо этого оно уже внутри инструкции, когда нам нужно. Компромисс в том, что там могут храниться только небольшие числа. Если быть точным, максимум 2 5 =32. Это наиболее полезно для увеличения счётчиков или значений. На ассемблере можно написать так:

Вот выдержка из спецификации:

Если бит [5] равен 0, то второй исходный операнд получают из SR2. Если бит [5] равен 1, то второй исходный операнд получают путём расширения значения imm5 до 16 бит. В обоих случаях второй исходный операнд добавляется к содержимому SR1, а результат сохраняется в DR. (стр. 526)

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

В спецификации есть последнее предложение:

Коды условий задаются в зависимости от того, является ли результат отрицательным, нулевым или положительным. (стр. 526)

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

Теперь мы готовы написать код для ADD :

В этом разделе много информации, поэтому подведём итоги.

LDI означает «косвенную» или «непрямую» загрузку (load indirect). Эта инструкция используется для загрузки в регистр значения из места в памяти. Спецификация на стр. 532.

Вот как выглядит двоичная компоновка:

какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Смотреть картинку какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Картинка про какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине. Фото какая команда ассемблера интел приведет к безусловному vmexit на гостевой машине

Это может показаться окольным путём для чтения из памяти, но так нужно. Инструкция LD ограничена адресным смещением 9 бит, тогда как память требует для адреса 16 бит. LDI полезна для загрузки значений, которые хранятся где-то за пределами текущего компьютера, но для их использования адрес конечного местоположения должен храниться рядом. Вы можете думать о ней как о локальной переменной в C, которая является указателем на некоторые данные:

Как и раньше, после записи значения в DR следует обновить флаги:

Коды условий задаются в зависимости от того, является ли результат отрицательным, нулевым или положительным. (стр. 532)

Вот код для данного случая: ( mem_read обсудим в следующем разделе):

7. Шпаргалка по инструкциям

В этом разделе — полные реализации оставшихся инструкций, если вы застряли.

Источник

Leave a Reply

Your email address will not be published. Required fields are marked *