如何将以下NASM代码转换为AT&T语法以修复"cannot handle non-absolute segment in jmp"错误



我是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

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

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

我相信你可能一直在尝试以下内容。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

然后在文件的稍后,您可以使用FARJMP,如下所示:

jmp $CODE64_SEL, $_start

相关内容

最新更新