Yasm с 64-битными инструкциями

Я пытаюсь собрать исходный код сборки для x86_64, написанный с синтаксисом Intel, который использует 64-битные регистры. Я использую следующие флаги командной строки:

yasm foo.asm -a x86 -m amd64

Я продолжаю получать ошибки, такие как:

warning: `rbp' is a register in 64-bit mode
foo.asm:23: error: undefined symbol `rbp' (first use)

Итак, я видел похожий вопрос в stackoverflow, а также многочисленные ресурсы в Интернете, которые указывают, что это проблему можно решить, указав директиву "BITS", например:

BITS 64

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

Есть ли способ указать директиву BITS во флаге командной строки, который я могу передать yasm?


person Siler    schedule 04.01.2018    source источник
comment
bits 64 просто говорит кодировать инструкции, предполагая, что код будет работать в 64-битном режиме.   -  person Michael Petch    schedule 04.01.2018
comment
-m amd64 согласно руководству.   -  person Jester    schedule 04.01.2018
comment
@Jester -m amd64 управляет форматом объектного файла, OP уже включил его. Однако я не понимаю, почему они не могут просто добавить BITS 64 и источник во временный файл.   -  person Margaret Bloom    schedule 04.01.2018
comment
@Jester: Согласно вопросу, он уже использует -m amd64. Я не знаю, является ли это вопросом OSDev или нет, но я предполагаю, что причина в том, что вы не указываете параметр -f, и по умолчанию используется значение -fbin, которое по умолчанию предполагает bits 16   -  person Michael Petch    schedule 04.01.2018
comment
Понятия не имею, как я пропустил -m amd64 в вопросе, я перестал читать на -a x86 :D   -  person Jester    schedule 04.01.2018
comment
Используйте -felf64 для создания 64-битных объектных файлов ELF, где BITS 64 используется по умолчанию. По возможности избегайте BITS, потому что он не меняет формат объектного файла, т. е. позволяет собрать 64-битный машинный код в исполняемый файл, который будет выполняться в 32-битном режиме. (Хотя, чтобы связать его, вам нужно будет использовать gcc -m32 или что-то в этом роде. Обычно проблема заключается в другом, когда люди используют .code32 в синтаксисе газа, где по умолчанию используется собственный режим для платформы, например x86-64).   -  person Peter Cordes    schedule 05.01.2018
comment
Это предполагает, что он хочет сделать исполняемый файл эльфа. Я не знаю, намеревался ли он не использовать опцию -f (по умолчанию -f bin. Если бы это было для проекта OSDev, то это имело бы смысл, но на самом деле недостаточно знать наверняка, как используется код -felf64 также может сделать предположение, что он не использует что-то вроде MacOS, где они могут использовать macho64 или Win64 в Windows.   -  person Michael Petch    schedule 05.01.2018
comment
Мы уверены, что yasm действительно поддерживает синтаксис Intel? Я не вижу ничего в их документах, что говорит об этом. Директива bits говорит только о том, какой код она собирается сгенерировать, а не о том, как она интерпретирует исходный код. Если yasm интерпретирует синтаксис Intel как at&t, то приведенные выше ошибки имеют смысл.   -  person David Wohlferd    schedule 05.01.2018


Ответы (2)


Используйте -felf64 для сборки кода x86-64 в 64-битный ELF .o.

Если вы создаете плоский двоичный файл (не .o или .obj), используйте BITS 64 в начале файла. В противном случае избегайте этого, обычно вы не хотите помещать 64-битный машинный код в 32-битный .o; ошибка времени сборки лучше.


Несмотря на документацию в руководстве, -a x86 -m amd64 опций YASM не переопределяет значение по умолчанию для стандартного -fbin плоского двоичного формата вывода, который должен ассемблироваться при условии, что код будет выполняться в 16-битном режиме. (Точно так же, как NASM).

Использование -m x86 не препятствует работе -felf64 или BITS 64 внутри файла. Это часть поддержки ограничений функций ЦП в YASM, которая может помочь предотвратить случайное использование функций ISA, не поддерживаемых целевым ЦП. (например, CPU Conroe AMD включает все до SSSE3 и инструкции AMD64, такие как syscall, при отключении SSE4 и AVX. По умолчанию нет ограничений.)


BITS 16 — это режим по умолчанию с -fbin.

Ассемблеру необходимо знать, в каком режиме ЦП должен выполнять ваш код. Например, mov eax,ecx равно 89 C8 в 32-битном режиме, но 66 89 C8 в 16-битном режиме (префикс переопределения размера операнда и затем тот же код операции + modrm, что и для 32-битного режима).

64-битный размер операнда и размер адреса, а также 64-битные регистры в целом кодируются только в 64-битном режиме, отсюда и ошибка при попытке ассемблировать код с использованием rbp, когда ассемблер создает код, который будет выполняться в 16-битном режиме. битовый режим.

Загрузчик, который запускается в 16-битном режиме, может переключиться на 32- и/или 64-битный режим, поэтому вам понадобится директива BITS 32 или BITS 64 перед целью перехода для jmp far, который переключается на 32-битный или 64-битный режим. режим.

Это обычный вариант использования директивы BITS. К сожалению, как и в случае с NASM, не существует параметра командной строки, который собирал бы плоский двоичный файл в выбранном вами режиме. Было бы здорово, если бы вы могли поместить inc eax в файл и получить 66 40, 40 или FF C0 без редактирования файла, просто используя параметры командной строки, но мы не можем.

person Peter Cordes    schedule 22.02.2019

Если я правильно понял, ваш вопрос: Как "активировать" 64-битный режим??

Это очень просто.

Если ваш код:

mov rax, [rbp - 2]
mov rbx, rax
syscall  ;just to call some or for end of code

Затем измените его на:

bits 64

mov rax, [rbp - 2]
mov rbx, rax
syscall  ;just to call some or for end of code

Проще говоря, поместите "биты 64" в начало вашего кода!

person Dr.Gray    schedule 22.02.2019
comment
И те ошибки, которые вы получаете, потому что: 1.) rbp 64 и обычно это 16-32. 2.) вторая ошибка возникает из-за предупреждения от первой ошибки из-за того, что не удалось сделать rbp - person Dr.Gray; 22.02.2019