2013-09-05 3 views
4

Я пытаюсь записать исходный код машинного кода в виде 0 и 1 в текстовый файл и выполнить его как через BIOS.Как определить значения кода операции x86 на основе действительных смещений и адресации в режиме реального времени?

У меня есть некоторые проблемы с пониманием того, как адресация, умножение, смещение, адресация, операнды и инструкции работают в комбинаторных устройствах, то есть разница между MOV AL, 07 и MOV BL, AL.

Я имею в виду, что это имеет смысл в Assembly, но в машинный код становится очень сложно получить представление о параметрах.

Итак, что я хочу знать, так это: Как я могу лучше понять это? Нет никаких учебников, которые я нашел, которые точно объясняют/описывают 0 и 1 из инструкций комбинаторных корреляций или соединений между передачей данных, MMIO, режимами адресации, арифметикой и т. П.

На этом сайте http://ref.x86asm.net/coder32.html#x00 он пытается, но я этого не понимаю.

ПРИМЕР: Скажем, я хочу переместить 5 в AL ... Я бы указал буквенный символ «5» в двоичном формате как часть кода операции в двоичном префиксе, закованном в цепочку с инструкцией AL/MOV, или я бы установил один фиксированный двоичный код для каждой команды, независимо от значения? Это то, что я хочу знать ... как понять, как написан машинный код.

+0

http://wiki.osdev.org/X86-64_Instruction_Encoding#ModR.2FM_and_SIB_bytes –

+1

Неясно, мой друг. –

ответ

1

Существует (в основном) взаимно однозначное сопоставление между ассемблерной мнемоникой и машинными инструкциями. Эти сопоставления можно найти в Intel Software Developers Manual, том 2, который содержит полные x86 16-, 32- и 64-разрядные наборы команд. Вероятно, вы захотите начать с . Глава 2: Формат инструкции, который описывает переводы, которые вы пытаетесь найти.

В случае mov al, 5 это так, как вы говорите, вы помещаете буквальный текст. Инструкция в машинном коде:

b0 05 

Поскольку то будет MOV r8, imm8 форма MOV инструкции. Для mov bl, al, вы хотите MOV r/m8,r8 форму, которая в вашем случае будет закодировать:

88 c3 

c3 вы можете посмотреть в таблице 2-2 32-битной адресацию формы с ModR/M байтами , где вы увидите его на пересечении строки BL и столбца AL. (Также есть 16-битная таблица, если это тот режим, в котором вы находитесь - значение в этом случае одинаковое.)

+0

Но машинный код находится в двоичном формате; вы указали шестнадцатеричный. b0 05 равно 176 или 10110000, а пять равно 101. Должен ли я пробивать шестнадцатеричные эквиваленты непосредственно в их соответствующем двоичном эквиваленте, а кодирование будет одинаковым? –

+0

Так в чем ваш смысл? '10110000 00000101' и' 10001000 11000011', то, если это заставляет вас чувствовать себя лучше. –

+0

Не обижайтесь, мне просто интересно. –

5

К сожалению, кодировка x86 является сложной и нерегулярной, и понимание этого - тяжелая работа. Лучшим «быстрым стартом» в кодировке является набор HTML-страниц на sandpile.org (он краткий, но довольно тщательный).

Первый: http://sandpile.org/x86/opc_enc.htm - в таблице «инструкции кодировки» показано примерно дюжина способов кодирования инструкций. Белые ячейки в каждой строке представляют собой обязательные байты в инструкции; следующие серые ячейки существуют (или нет) на основе различных полей, появляющихся ранее в коде операции. Вы должны посмотреть на строки, начинающиеся с белого «0Fh», а также с первой строкой. В нижней части той же страницы находятся битовые поля, появляющиеся в разных «расширенных» полях кода операции - вы игнорируете все, кроме строки «modrm/sib» (первая строка).

Обратите внимание, что для всех, кроме первой строки (которая является 1-байтовым кодом операции), байты мод-г/м должны следовать коду операции (для 1-байтовых кодов операций это зависит от инструкции). Это кодирует аргументы для большинства инструкций с двумя аргументами. Таблица в http://sandpile.org/x86/opc_rm.htm имеет значения: один из аргументов должен быть регистром, другой аргумент может быть регистром или косвенной памятью (поле «reg» кодирует регистр, поля «mod» и «r/m» кодируют другой аргумент). Обычно также есть бит «direction» в другом месте кода операции, указывающий порядок аргументов. Код операции также указывает, будем ли мы манипулировать, например, AL, AX, EAX или RAX (т. Е. Разные размеры) или один из расширенных регистров, поэтому каждое трехбитовое поле указывается как ссылка на множество разных регистров.

В modrm, если бит «mod» равен «11», то поле «r/m» также относится к регистру. В противном случае он обычно ссылается на адрес памяти, созданный путем добавления именованного регистра в (необязательное) смещение, появляющееся после байта modrm (эта константа имеет длину 0, 1 или 4 байта в зависимости от бит «mod»). Исключением является то, что бит «r/m» равен «100» (то есть 0x4), который обычно называют «SP» - в этом случае аргумент памяти описывается дополнительным байтом «sib», который сразу же следует за байтом modrm (любое смещение modrm появляется после сиба). Для кодирования SIB просмотрите http://sandpile.org/x86/opc_sib.htm или перейдите на страницу modrm.

И наконец, чтобы понять, откуда взялись направление и размер, посмотрите на некоторые коды операций: http://sandpile.org/x86/opc_1.htm. Первые четыре записи - это «ADD», с аргументами в двух разных порядках и имеющие две разные ширины. Поэтому в этом случае нижние биты команды кодируют направление и ширину.

+2

Еще одна вещь: если вы C-грамотный, вы можете посмотреть на один из (нескольких) сборщиков или дизассемблеров с открытым исходным кодом, которые имеют всю информацию о кодах операций, организованную в таблицах. Например, таблица (GPL'd) GNU binutils x86 находится в файле с именем «i386-opc.c» или «i386-opc.tbl» в зависимости от версии (google the filename); один экземпляр находится здесь: https://github.com/adobe-flash/crossbridge/blob/master/gdb-7.3/opcodes/i386-opc.tbl – mike

+0

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

+0

вы можете увидеть способ декодирования tbl здесь https://cygwin.com/ml/binutils/2010-09/msg00277.html таблица основана на заголовке здесь https://github.com/arrogantpenguin/PenguinoOS/ BLOB/73608ed45a03cd3b013303e60accc5dee473ec53/источники/Binutils/опкоды/i386-opc.h # L660 – h4ck3rm1k3