我正在写一个玩具操作系统来学习它的工作原理,在这里我遇到了一个小问题。我想跳远,如下:
ljmp $0x9000, *(%ax)
段地址是0x9000,偏移地址存储在寄存器ax
中(目前我仍处于实模式下),我尝试过以下操作,但没有一个工作。
ljmp $0x9000, ax
ljmp $0x9000, %ax
ljmp $0x9000, (%ax)
ljmp $0x9000, *(%ax)
那怎么办呢?我正在使用GNU AS(i686-elf-as)。
答案 0 :(得分:2)
在x86中,您没有尝试这样的指令。您需要做的是将内存地址0x9000:ax
存储到内存中,然后间接跳转到该地址。
FF /5 JMP m16:16 Jump far, absolute indirect, address given in m16:16
所以代码应该是这样的:
.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
答案 1 :(得分:2)
作为“nrz”方法的替代方法,您也可以推送0x9000和AX并执行RETF:
pushw $0x9000
push %ax
retf
注意:在原始的8086和8088上,即使“pushw $ xxxx”指令也不存在......