2013-05-03 1 views
1

Я пытаюсь определить постоянную запись IDT (Interrupt Descriptor Table) в NASM, и для этого мне нужно испустить в таблицу данных высокое слово двойного слова адрес , который не разрешен до момента ссылки. Есть ли способ сделать это?NASM: emit MSW значения нескалярного (link-time)

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

;;; 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 правильно вызывает ЛД испускать младшее слово адреса Int3, но старшее слово терпит неудачу при сборке с эта ошибка:

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

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

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

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


Частности:

  • NASM 2.20.01
  • выходной формат NASM "Aout"
  • Ld версии 2.22
  • 32-битный режим (NASM "биты 32", выданные директивы)
+0

См. Также: http: // stackoverflow.com/questions/12861843/static-defined-idt? rq = 1. Строго говоря, этот вопрос является дубликатом этого вопроса - это та же проблема, с той же причиной (ld + swizzled IDT), но с разными языками. –

ответ

1

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

dw (int3 - $$) >> 16

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

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

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

+0

Спасибо за ответ. Я собираюсь в «-f aout», но «-f elf32» ничего не меняет: в любом случае ORG отклоняется nasm, так как я не генерирую плоский двоичный файл. Я предполагаю, что это указывает на «обходное решение» («часть» моей программы), если я не хочу строить IDT во время выполнения. Re «Не делай этого»: :) –