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 ничего не выводит! Не делай этого - ты тратишь много времени!