我知道我成功地使用int 13h
将代码写入该地址,因为我可以在该内存位置看到它。我不能做的就是跳到那里。
我把0x1000
(在那里三个零)放入es
和0x0000
到bx
我知道[es:bx]
意味着(es * 0x10) + bx
计算的地址与0x10000
相等(那里有四个零)。但eip
,指令指针,永远不会去那里。
我尝试了jmp [es:bx]
,jmp 0x1000:0x0000
,以及NASM
甚至不接受的一堆其他排列。
我目前的启动加载程序(仍然无法正常工作)是here。我在Qemu启动它并在0x10000
的前50个字节上做了一个memsave,用调整打开它,并在那里看到我的“内核”代码(简单。但是EIP
仍然拒绝成为0x10000
,或者到达它然后挂在哪里我想要它,就是我的意思)。 here情况的完整图像
远跳不能使用只为段使用内存位置。您可以通过以下几种方式执行此操作:
1)段和偏移的简单硬编码地址。
jmp 0x1000:0
2)使用完整地址进行间接跳转:
entry dw 0x0000 ; offset
dw 0x1000 ; segment
jmp far dword ptr [entry] ; far jump (syntax might differ)
3)远回报
push SYSADDR ; segment
push 0 ; offset
retf ; far return
在DOS时间使用的常见技巧是修补指令:
mov ax, SYSADDR
mov word ptr [myjump+3], ax
myjump:
jmp 0x0000:0x0000
或者将其中一部分用作变量:
myjump:
db 0xEA ; far jmp opcode
dw 0x0000 ; offset part
SYSADDR dw 0x1000 ; segment part
免责声明:所有上述内容都来自内存,我可能会遇到一些错误的部分(例如,段/偏移的顺序非常混乱)。
你应该能够完全按照自己的意愿行事。这是一个做同样事情的例子,可能是出于同样的原因:
; http://www.free2code.net/tutorials/view/writing_your_own_operating_system-12/page1.html
...
mov bx,0x1000 ;Es and Bx put together are where to load the program too
; (see jmp x1000:0x00)
mov es,bx
mov bx,0x00
int 13h ;Int 13 is all functions for disks
...