How to far jump to $0x9000:%ax using AT&T syntax?

2.8k views Asked by At

I'm writing a toy os to learn the workings of it, here I came into a little problem. I want to do a long jump, just as follows:

ljmp $0x9000, *(%ax)

The section address is 0x9000, the offset address is stored in the register ax (currently I'm still under real mode), I've tried the following, none of them worked.

ljmp $0x9000, ax
ljmp $0x9000, %ax
ljmp $0x9000, (%ax)
ljmp $0x9000, *(%ax)

So how to do the trick? I'm using GNU AS (i686-elf-as).

2

There are 2 answers

0
Martin Rosenau On BEST ANSWER

As an alternative to "nrz"'s method you may also push 0x9000 and AX and perform a RETF:

pushw $0x9000
push %ax
retf

Note: On original 8086s and 8088s even the "pushw $xxxx" instruction does not exist...

0
nrz On

In x86 there is no such instruction you are attempting to do. What you need to do is to store the memory address 0x9000:ax into memory and then do an indirect jump to that address.

The indirect jump is this one (IntelĀ® 64 and IA-32 architectures software developer's manual combined volumes: 1, 2A, 2B, 2C, 3A, 3B, and 3C):

FF /5 JMP m16:16 Jump far, absolute indirect, address given in m16:16

So the code should be something like this:

.code16
movw $0x9000, ($jump_address_segment)
movw %ax, ($jump_address_offset)
ljmp *($jump_address_offset)

.data
jump_address_offset:  .word 0
jump_address_segment: .word 0