3

我试图在NASM中定义一个常量IDT (Interrupt Descriptor Table)条目,为此,我需要将双字地址的高位字发送到数据表中,直到链接时间才解析。有没有办法做到这一点?

这是中断处理程序:

;;; 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:错误:移位运算符只能应用于标量值

NASM 不会对链接时间之前未定义的值进行数学运算。我明白,但我需要一种方法来解决这个问题。我可以:

  • 绝对定位 int3
  • 在运行时而不是在装配时构建 IDT

我可能最终会在运行时构建 IDT,但最好知道是否有办法使汇编器/链接器将地址的高位字发送到数据表中,该地址的高位字直到链接时才被解析.


细节:

  • NASM 2.20.01 1
  • NASM 输出格式aout
  • LD 2.22 版
  • 32 位模式(NASM“bits 32”指令发布)

1这可能是一个错字;今天我的发行版中的最新版本是 2.12.01。我写这个问题时可用的最新版本的 nasm 是 2.10.01。

4

1 回答 1

3

嗯......你可能知道,Nasm 会屈尊改变两个标签之间的差异。通常的构造类似于:

dw (int3 - $$) >> 16

where$$指的是该部分的开头。这会计算“文件偏移量”。这可能不是您想要转移的值。

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

可以做你想做的事……在哪里……好吧,如果我们使用平面二进制文件,ORIGIN我们告诉 Nasm 的内容。org我假设您正在组装到-f elf32or -f elf64,告诉 ld --oformat=binary,并在链接器脚本或命令行中告诉 ld 您想要.text的位置(?)。这似乎有效。我做了一个有趣的发现:如果你告诉 ld -oformat=binary(一个连字符)而不是--oformat=binary(两个连字符),ld 默默地什么也不输出!不要这样做——你会浪费很多时间!

于 2013-05-03T09:13:06.643 回答