第三章 保护模式 pmtest2.asm添加实现段间间接远转移代码

来源:互联网 发布:asp连接access数据库 编辑:程序博客网 时间:2024/06/03 17:31

一、Intel 段间间接远跳转

格式: jmp    dword ptr orp

执行的操作:

( IP ) < ---  ( EA )

( CS ) <---- ( EA + 2 )

对于386及其后继机型:

( EIP ) <------ ( EA )

( CS ) <------- ( EA + 4)

其中EA为内存地址,

二、动手操作

1.在[SECTION .data1]中添加两个变量来存放跳转目标处的段基址和偏移

即为CSValueInRealMode和IPValueInRealMode,注意前者即CS为dw,IP为dd

还有保证在DateLen标号之前,曾今我把这两个变量放到DataLen之后,编译时间很长,而且生成的目标文件达到1.5G之多,肯定无法运行了,惨痛的教训啊!谨记

[SECTION .data1]ALIGN 32[BITS   32]LABEL_DATA:SPValueInRealMode       dw      0PMMessage               db      "In Protected Mode now. ^-^", 0OffsetPMMessage         equ     PMMessage - $$StrTest                 db      "ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0OffsetStrTest           equ     StrTest - $$IPValueInRealMode       dd      0CSValueInRealMode       dw      0DataLen                 equ     $ - LABEL_DATA; END OF [SECTION .data1]=====================================

2.在[SECTION .s16]中为CSValueInRealMode赋值,因为我们实在不同的段间跳转,而且这两个对象不仅代码段不同,数据段,堆栈段都不同,所以我们还要通过寄存器把DS值传到[SECTION .s16code]中,这里先把ds的值压栈中
            mov     ax, cs            mov     ds, ax            mov     es, ax            mov     ss, ax            mov     sp, 0100h                       mov     [CSValueInRealMode], ax             push     ax            ;mov     [LABEL_GO_BACK_TO_REAL + 3], ax            mov     [SPValueInRealMode], sp

3.在跳转到保护模式之前弹出堆栈内容到ax
; switch into Protected Mode            pop     ax            jmp dword SelectorCode32:0
4.在保护模式中临时保存ds的值到
[SECTION .scode32][BITS   32]LABEL_SEG_CODE32:            mov     bx, ax            mov     ax, SelectorData            mov     ds, ax            mov     ax, SelectorTest            mov     es, ax            mov     ax, SelectorVideo            mov     gs, ax            mov     ax, SelectorStack            mov     ss, ax            mov     esp, TopOfStack

5.关键时刻,来到了[SECTION .scode16]

LABEL_GO_BACK_TO_REAL:            ;jmp     0:LABEL_REAL_ENTRY            mov     ax,  bx            mov     ds, ax            mov     [IPValueInRealMode], dword LABEL_REAL_ENTRY            jmp     dword far [IPValueInRealMode]

三、小结

很显然,我这个方法没有作者的简单。但从这个小尝试我学到了很多,细节啊,太重要了啊!

此外,还发现一个奇怪的现象,如果没有保存edx的值前对它进行了赋值操作,结果是我们最后可以返回dos出现问题,没有提示符,而且我想显示的一段字符串也没有显示,调试发现在程序运行之前edx的值是0x40000,而且在正常成功返回dos时也是这个值,于是,我尝试在修改edx之后,在给它赋值0x40000,果不出我所料,成功返回到dos,一切正常,这个0x40000大概存放着特定的东东吧。


原创粉丝点击