NASM:发出非标量(链接时间)值的MSW

时间:2013-05-03 05:01:23

标签: assembly nasm interrupt ld ia-32

我试图在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不会使用在链接时间之前未定义的值进行数学运算。我理解,但我需要一种方法来解决这个问题。我可以:

  • 绝对定位int3
  • 在运行时而不是汇编时建立IDT

我可能最终会在运行时构建IDT,但是最好知道是否有办法让汇编器/链接器向数据表中发出未解析的地址的高位字直到链接时间。


情况:

  • NASM 2.20.01
  • nasm输出格式“aout”
  • ld version 2.22
  • 32位模式(发布了nasm“位32”指令)

1 个答案:

答案 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默默输出任何内容!不要这样做 - 你浪费了很多时间!