How to convert the following NASM code into AT&T syntax so as to fix the "cannot handle non-absolute segment in jmp" error

Viewed 665

I am new at AT&T syntax. I want to convert the following NASM syntax code into AT&T syntax just for the sake of understanding.

My try to convert it into AT&T syntax:

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'

The NASM code:

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
1 Answers

In GAS since the definition of your GDT appears after the jmp $gdtcode, $_start, the assembler will see the JMP and believe the symbol gdtcode is an external symbol (that will be relocated by the linker) and not a constant. Because of that it will complain about the non-absolute references.

You also improperly define your GDT by placing .word .- gdt after gdtcode: and gdtdata. Those lines will emit a 16-bit word into GDT where you don't want them.

I believe you might have been trying for something like the following. GDT is defined at some point before the JMP:

gdt:
.quad 0x0000000000000000

gdtcode:
.quad 0x0020980000000000

gdtdata:
.quad 0x0000900000000000

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

CODE64_SEL = gdtcode-gdt
DATA64_SEL = gdtdata-gdt

And then at a later point in the file you can use a FAR JMP like this:

jmp $CODE64_SEL, $_start
Related