NASM: испускать MSW не скалярного (связанного времени) значения

Я пытаюсь определить постоянную запись IDT (Таблица дескрипторов прерываний) в NASM, и для этого мне нужно выдать в таблицу данных старшее слово адреса двойного слова , которое не разрешается до времени соединения. Есть ли способ сделать это?

Вот обработчик прерывания:

;;; Interrupt 3 (breakpoint) handler.  For now, just poke the screen and halt.

        align   8
int3:
        mov     [0xb8000],dword '* * '
        hlt

И вот запись IDT, которая ссылается на это. Наиболее значимые и наименее значимые слова смещения должны храниться отдельно и не непрерывно:

        ;; Interrupt 3 - breakpoint
        dw      int3                    ; offset (low)    <---- WORKS
        dw      codesel                 ; code selector
        db      0                       ; unused
        db      0b10001111              ; present, ring 0, 32-bit trap gate
        dw      int3 >> 16              ; offset (high)   <---- ASSEMBLY ERROR

NASM корректно заставляет ld выдавать младшее слово адреса int3, но старшее слово терпит неудачу при сборке с этой ошибкой:

 pgm.asm:240: error: shift operator may only be applied to scalar values

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

  • найдите int3 абсолютно
  • Постройте IDT во время выполнения вместо времени сборки

Я, вероятно, в конечном итоге построю IDT во время выполнения, но было бы хорошо узнать, есть ли способ заставить ассемблер / компоновщик выдавать в таблицу данных старшее слово адреса, которое не разрешается до времени ссылки,


Частности:

  • NASM 2.20.01
  • выходной формат носа "аут"
  • лд версия 2.22
  • 32-битный режим (выдана директива nasm "бит 32")

1 ответ

Ну... как вы, наверное, знаете, Nasm снизойдет до разницы между двумя ярлыками. Обычная конструкция что-то вроде:

dw (int3 - $$) >> 16

где $$ относится к началу раздела. Это вычисляет "смещение файла". Вероятно, это не то значение, которое вы хотите изменить.

dw (int3 - $$ + ORIGIN) >> 16

может делать что хочешь... где ORIGIN это... хорошо, что мы сказали Nasm для org, если бы мы использовали плоский двоичный файл. Я предполагаю, что вы собираете -f elf32 или же -f elf64, говоря л.д. --oformat=binaryи сообщая ld либо в скрипте компоновщика, либо в командной строке, где вы хотите .text быть (?). Это похоже на работу. Я сделал интересное открытие: если вы скажете ld -oformat=binary (один дефис) вместо --oformat=binary (два дефиса) ld ничего не выводит! Не делай этого - ты тратишь много времени!

Другие вопросы по тегам