【问题标题】:How to convert the following NASM code into AT&T syntax so as to fix the "cannot handle non-absolute segment in jmp" error如何将以下 NASM 代码转换为 AT&T 语法以修复“无法处理 jmp 中的非绝对段”错误
【发布时间】:2019-05-24 20:49:55
【问题描述】:

我是 AT&T 语法的新手。为了便于理解,我想将以下 NASM 语法代码转换为 AT&T 语法。

我尝试将其转换为 AT&T 语法:

lgdt (gdtpointer)

jmp $gdtcode, $_start

gdt:
.quad 0x0000000000000000

gdtcode: 
.word .- gdt
.quad 0x0020980000000000                   

gdtdata: 
.word .- gdt
.quad 0x0000900000000000                   

gdtpointer:
.word .-gdt-1
.quad gdt   

Error: can't handle non absolute segment in `jmp'

NASM 代码:

lgdt [gdt.pointer]          

jmp gdt.code:startLongMode

;Global Descriptor Table
gdt:
dq 0x0000000000000000               

.code equ $ - gdt
dq 0x0020980000000000                   

.data equ $ - gdt
dq 0x0000930000000000                   

.pointer:
dw $-gdt-1                  
dq gdt                  

                   ;Ref: Intel System Programming Manual V1 - 2.1.1.1

【问题讨论】:

  • .word .- gdt 实际上将一个单词发送到内存中。 .equ 是 NASM equ 的 GAS 等价物。参见手册:sourceware.org/binutils/docs/as/Equ.html#Equ
  • 感谢彼得,但我提到的错误仍然存​​在! :(
  • 你用什么命令来组装这个?
  • gcc -Wl,--oformat=binary -Wl,-Ttext=0x7c00 -Wl,--build-id=none -n​​ostartfiles -nostdlib -m32 -o test test.s
  • 天哪,非常感谢@MichaelPetch ...

标签: assembly x86 nasm bootloader att


【解决方案1】:

在 GAS 中,由于 GDT 的定义出现在 jmp $gdtcode, $_start 之后,汇编器将看到 JMP 并认为符号 gdtcode 是外部符号(将由链接器重新定位) 而不是常数。因此,它会抱怨非绝对引用。

您还通过在gdtcode:gdtdata 之后放置.word .- gdt 来不正确地定义您的GDT。这些行会在您不需要它们的地方向 GDT 发出一个 16 位字。

我相信您可能一直在尝试以下内容。 GDT 在JMP之前的某个时间点定义:

gdt:
.quad 0x0000000000000000

gdtcode:
.quad 0x0020980000000000

gdtdata:
.quad 0x0000900000000000

gdtpointer:
.word .-gdt-1
.quad gdt

CODE64_SEL = gdtcode-gdt
DATA64_SEL = gdtdata-gdt

然后在文件的稍后位置,您可以像这样使用 FAR JMP

jmp $CODE64_SEL, $_start

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多