Включение заголовочного файла в файл сборки - PullRequest
0 голосов
/ 12 февраля 2020

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

Ниже мой main.S файл

#include "common.h"
BEGIN
    mov $0x0E40, %ax
    int $0x10
    hlt

Ниже мой common.h file:

.macro BEGIN
    LOCAL after_locals
    .code16
    cli
    ljmp $0, $1f
    1:
    xor %ax, %ax
    /* We must zero %ds for any data access. */
    mov %ax, %ds
    mov %ax, %es
    mov %ax, %fs
    mov %ax, %gs
    mov %ax, %bp
    /* Automatically disables interrupts until the end of the next instruction. */
    mov %ax, %ss
    /* We should set SP because BIOS calls may depend on that. TODO confirm. */
    mov %bp, %sp
    /* Store the initial dl to load stage 2 later on. */
    mov %dl, initial_dl
    jmp after_locals
    initial_dl: .byte 0
after_locals:
.endm

Оба файла находятся в одном каталоге. Когда я делаю компиляцию:

$ as --32 -o main.o main.S
main.S: Assembler messages:
main.S:2: Error: no such instruction: `begin'

Что мне не хватает? Я провел небольшое исследование и получил этот ответ в SO, но это не помогло. Пожалуйста, помогите.

1 Ответ

3 голосов
/ 13 февраля 2020

$ as --32 -o main.o main.S

as - это просто ассемблер, он переводит исходный код сборки в объектный код. Он не запускает препроцессор C, который должен расширяться #include.

(# - это символ комментария в синтаксисе GAS для x86, поэтому строка рассматривается как комментарий, если она видна вместо ассемблера вместо CPP)

Что вы можете сделать:

  1. Используйте gcc для сборки с соответствующим суффиксом файла (.S или .sx), он запустит препроцессор C перед запуском ассемблера.
    • Добавьте -v, чтобы увидеть, какие команды gcc вызывает.
    • Если ваш источник имеет другой суффикс, вы можете -x assembler-with-cpp source.asm.
    • Если вы хотите см. промежуточный результат после предварительной обработки, добавьте -save-temps. Это позволит записать файл .s с предварительно обработанным источником.
    • Если вы хотите передать параметр командной строки в as, вы можете, например, -Wa,--32. Однако в данном случае лучше использовать параметры, которые понимает драйвер компилятора, например -m32 или -m16. Драйвер знает о таких опциях, например, он также обслужит соответствующие опции при связывании, если вы связываетесь с gcc -m32 ..., как указано ниже.
  2. Используйте .include директива ассемблера, которая обрабатывается самим ассемблером, а не препроцессором C.

Примечание: В случае 1. добавление включает пути поиска с помощью -I path может работать не так, как ожидалось: драйвер компилятора (в данном случае gcc) добавит -I path только в командную строку ассемблера, если он знает, что это ассемблер GNU. Вы можете сказать это, когда компилятор сконфигурирован с помощью флага конфигурации --with-gnu-as.

Примечание: Аналогичное относится к связыванию. Возможно, вы не захотите вызывать компоновщик (ld вручную), если вы не создаете исполняемый или простой двоичный файл stati c; используйте gcc или g++ вместо этого, если вы делаете обычный исполняемый файл для запуска на хост-системе. Он добавит много опций, необходимых для компоновки, таких как многолабильные пути, пути поиска и т. Д. c. который вы не хотите возиться вручную.

(int $0x10 - это 16-битный вызов B IOS, однако, который не будет работать в современной основной ОС, только в DOS или в устаревшей версии B IOS загрузчик.)

...