• Linux0.11——第二回 从0x7c00到0x90000


    上一讲,讲了CPU执行操作系统的最开始的两行代码:

    mov ax, 0x07c0
    mov ds, ax
    
    • 1
    • 2

    这两行代码将数据段寄存器 ds 的值变成了 0x07c0,方便之后访问内存时,利用这个段基址进行寻址。

    接下来的代码:

    mov ax,0x9000
    mov es,ax
    mov cx,#256
    sub si,si
    sub di,di
    rep movw
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    此时,ds 寄存器的值已经是 0x07c0 了,然后又通过同样的方式将 es 寄存器的值变成 0x9000,接着又把 cx 寄存器的值变成 256(代码里确实是用十进制表示的,与其他地方有些不一致,不过不影响)。现在 ds、es 和 cx 寄存器的值就都被赋上了确定的值了,

    其中sub指令,就是sub a,b意思就是a = a - b
    因此sub si,si sub di,di就是表示这两个寄存器的值为0

    这样一来上面的代码的结果就是

    ds = 0x07c0
    es = 0x9000
    cx = 256
    si = 0
    di = 0
    在这里插入图片描述

    这上面的六条指令都是为了服务后面的rep movw这条指令,movw表示复制一个字也就是2个字节,
    根据这行指令,自然就会引出以下三个问题:

    1. 重复执行多少次呢?答案是 cx 寄存器中的值,也就是 256 次。
    2. 从哪复制到哪呢?答案是从 ds:si 处复制到 es:di 处,也就是从 0x7c00 复制到 0x90000。
    3. 一次复制多少呢?刚刚说过了,复制一个字 16 位,也就是两个字节。那么。一共复制 256 次的两个字节,其实就是复制 512 个字节。

    总结一下就是,将启动区的512字节,又把它移动到0x90000处开始的512字节处,也就是下面的样子:
    在这里插入图片描述

    我理解的就是:0x7c00这个地址位置比较靠前,为了操作系统的代码不被覆盖,把它先移动到比较靠后的位置。现在操作系统最开始的代码位于0x90000处了,再往后看代码会发现这是一条跳转指令了:

    	jmpi go, 0x9000
    go:	mov	ax,cs
    	mov	ds,ax
    	mov	es,ax
    
    • 1
    • 2
    • 3
    • 4

    jmpi 是一个段间跳转指令,表示跳转到 0x9000:go 处执行。
    这里寻址方式依然是段基址先左移4位,再加上偏移地址。段基址左移4位就是0x90000, 因此最后的效果就是跳转到0x90000 + go这个内存地址处执行。

    go在这里就是一个标签,学过汇编都知道,这里最终编译成机器码的时候会被翻译成一个值,这个值就是go这个标签在文件内的偏移地址。当然比较准确的说法就是,bootsect.s编译成二进制文件bootsect后,go这个标签在被编译成二进制文件里的内存地址偏移量。

    这个偏移地址加上0x90000,就刚好是go标签处的那行代码,mov ax, cs此时所在的内存地址了。
    其实,就是接着bootsect.s这个文件的代码继续执行而已,因为前面的移动代码已经执行过了。

    在这里插入图片描述
    假如 mov ax,cs 这行代码位于最终编译好的二进制文件的 0x08 处,那 go 就等于 0x08,而最终 CPU 跳转到的地址就是 0x90008 处。

    总结

    • 第一讲就是由BIOS把启动区的代码复制到内存地址0x7c00处,由于x86寻址方式的历史兼容原因,所以需要段基址左移4位,然后就是把0x7c00的512启动区的数据复制到0x90000地址处。然后接着运行。
  • 相关阅读:
    线程进程协程
    8.0MGR单主模式搭建_克隆(clone)插件方式
    美国信用卡返现率优化到3%-5%,AI优化算法的应用
    Allegro如何制作routekeepin操作指导
    tensorflow2从入门到精通——自编码器系列原理以及实现
    【Designing ML Systems】第 8 章 :数据分布转移和监控
    机器学习实战 | SKLearn最全应用指南
    Android 源码解析: SharedPreferences的解析
    变配电智能化系统:提高效率与安全性
    通过WinSCP实现Windows给Ubuntu(Linux)虚拟机传输数据
  • 原文地址:https://blog.csdn.net/qq_43460068/article/details/133218953