免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1457 | 回复: 4
打印 上一主题 下一主题

[内核入门] 如何跳入保护模式 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2014-04-29 18:07 |只看该作者 |倒序浏览
; 初始化 32 位代码段描述符
        xor        eax, eax
        mov        ax, cs
        shl        eax, 4
        add        eax, LABEL_SEG_CODE32
        mov        word [LABEL_DESC_CODE32 + 2], ax
        shr        eax, 16
        mov        byte [LABEL_DESC_CODE32 + 4], al
        mov        byte [LABEL_DESC_CODE32 + 7], ah
以上是对某个全局代码段描述符中基地址的设置,其中LABEL_SEG_CODE32是进入保护模式后执行代码处的标号,跳入保护模式的命令为:jmp        dword SelectorCode32:0
其中选择符SelectorCode32对应于描述符LABEL_DESC_CODE32。

我对以上代码进行了修改,在对描述符LABEL_DESC_CODE32基地址的设置时没有加上标号LABEL_SEG_CODE32,即没有add        eax, LABEL_SEG_CODE32这段代码,然后jmp        dword SelectorCode32:LABEL_SEG_CODE32。为什么不对呢?我感觉逻辑上没什么错误呀,是不是语法上有错误?我使用的是nasm

论坛徽章:
0
2 [报告]
发表于 2014-04-29 18:41 |只看该作者
回复 1# stuman


Hi, stuman,
  1. jmp        dword SelectorCode32:0
  2. jmp        dword SelectorCode32:LABEL_SEG_CODE32
复制代码
为什么不对呢?我感觉逻辑上没什么错误呀,是不是语法上有错误?我使用的是nasm

不对是指?
事实上如果LABEL_SEG_CODE32不是0的话,你怎么能寄望他们的行为一样呢。

你用的是nasm, 那语法没错,有错编译应该也不会过吧。
  

论坛徽章:
0
3 [报告]
发表于 2014-04-29 18:49 |只看该作者
我说的“不对”是指使用jmp        dword SelectorCode32:LABEL_SEG_CODE32。代码运行时会出错。
我看其他书上有使用类似jmp        dword SelectorCode32:LABEL_SEG_CODE32的代码,所以我想修改这里的代码,想看看这种方式下怎么写才是正确的。当然那部分代码我没仔细看,所以我只好发帖提问了。
保护模式下,物理地址为描述符中段地址加eip中值,所以我觉得这两种方法应该都正确呀,因为最终物理地址都是一样的

论坛徽章:
0
4 [报告]
发表于 2014-04-29 18:50 |只看该作者
本帖最后由 l4rmbr 于 2014-04-29 18:59 编辑

回复 3# stuman

LABEL_SEG_CODE32的值是? 运行出错信息是?


网上找到这么一段,你可以对照下,看你的情况跟这有什么不同:
  1. The most common form of mixed-size instruction is the one used when writing a 32-bit OS: having done your setup in 16-bit mode, such as loading the kernel, you then have to boot it by switching into protected mode and jumping to the 32-bit kernel start address. In a fully 32-bit OS, this tends to be the only mixed-size instruction you need, since everything before it can be done in pure 16-bit code, and everything after it can be pure 32-bit.

  2. This jump must specify a 48-bit far address, since the target segment is a 32-bit one. However, it must be assembled in a 16-bit segment, so just coding, for example,

  3.         jmp     0x1234:0x56789ABC       ; wrong!
  4. will not work, since the offset part of the address will be truncated to 0x9ABC and the jump will be an ordinary 16-bit far one.

  5. The Linux kernel setup code gets round the inability of as86 to generate the required instruction by coding it manually, using DB instructions. NASM can go one better than that, by actually generating the right instruction itself. Here's how to do it right:

  6.         jmp     dword 0x1234:0x56789ABC         ; right
  7. The DWORD prefix (strictly speaking, it should come after the colon, since it is declaring the offset field to be a doubleword; but NASM will accept either form, since both are unambiguous) forces the offset part to be treated as far, in the assumption that you are deliberately writing a jump from a 16-bit segment to a 32-bit one.
复制代码

论坛徽章:
0
5 [报告]
发表于 2014-04-29 19:04 |只看该作者
LABEL_SEG_CODE32是保护模式下运行代码的最开始处标号,我是在虚拟机上运行的,出错信息没什么用
感谢楼上贴的英文,不过和我的问题无关
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP