我试图在IDT (Interrupt Descriptor Table)中定义一个常量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不会使用在链接时间之前未定义的值进行数学运算。我理解,但我需要一种方法来解决这个问题。我可以:
我可能最终会在运行时构建IDT,但是最好知道是否有办法让汇编器/链接器向数据表中发出未解析的地址的高位字直到链接时间。
情况:
答案 0 :(得分:1)
嗯......正如你可能知道的那样,纳斯姆会屈服于改变两个品牌之间的差异。通常的构造类似于:
dw (int3 - $$) >> 16
其中$$
指的是该部分的开头。这会计算“文件偏移量”。这可能不是你想要改变的价值。
dw (int3 - $$ + ORIGIN) >> 16
可能会做你想要的......在ORIGIN
是......嗯,如果我们使用平面二进制文件,我们告诉Nasm org
。我假设您要汇编到-f elf32
或-f elf64
,告诉ld --oformat=binary
,并在链接器脚本或命令行中告诉ld您希望.text
成为{1}} (?)。这似乎有效。
我做了一个有趣的发现:如果你告诉ld -oformat=binary
(一个连字符)而不是--oformat=binary
(两个连字符),ld默默输出任何内容!不要这样做 - 你浪费了很多时间!