• 【os-tutorial】四,电脑存储的组织形式


    在进行学习之前,先看一下这幅图
    在这里插入图片描述
    这幅图为16bit实模式下电脑启动后的内存存储结构,读者请尤其注意粉色椭圆勾选的区域.
    实验一
    我们想要通过boot_sector的代码将大写字母"X"打印在屏幕上,为此设计了一组实验,实验设计见源码.

    源码

    ; ===============================================================
    ; 文件名: boot_sect_memory.asm
    ; 本程序尝试打印一个"X",使用的方法为向AH传入0x0E,向AL传入待打印内容,即"X"
    ; 待打印内容定义为标签"the_secret"的形式
    ; ===============================================================
    mov ah, 0x0e
    
    ; 尝试一
    ; 将标签赋值给AL,试图打印内容
    ; 结果:当然会失败,稍有汇编知识的人都知道,the_secret只是
    ; 一个地址,无法用地址代替内容
    
    mov al, "1"
    int 0x10
    mov al, the_secret
    int 0x10
    
    ; 尝试二
    ; 将标签指向的内容赋值给AL,试图打印内容
    ; 结果:失败
    ; 失败原因:BIOS将我们的boot_sector(本程序)编译出的二进制文件
    ; 放置在0x7C00的位置上,而[the_secret]只表示该标签指向的内容相对于地址0; 地址
    
    mov al, "2"
    int 0x10
    mov al, [the_secret]
    int 0x10
    
    ; 尝试三
    ; 在尝试二的基础上,获得the_secret指向的内容的绝对地址
    ; 绝对地址的形式为: 0x7c00 + 相对于地址0的地址([the_secret])
    ; 结果:成功
    mov al, "3"
    int 0x10
    mov bx, the_secret
    add bx, 0x7c00
    mov al, [bx]
    int 0x10
    
    ; 在当前位置循环运行
    jmp $
    
    the_secret:
        db "X"
    
    times 510 - ($ - $$) db 0
    dw 0xAA55
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    编译并Boot

    具体编译并Boot方法参见【os-tutorial】 (二) boot_sector的"裸骨架"的编译、Boot部分

    试验结果

    在这里插入图片描述

    新知识
    如果每次对变量进行寻址都需要加上0x7C00,那岂不是太麻烦了,因此人们设计了汇编语法

    org  段地址
    
    • 1

    使用该语法,使后续的寻址基地址都变为段地址.

    实验二

    接下来我们将"org 段地址"写入我们的源码第一行中,看看会有什么样的结果.

    编译并Boot

    具体编译并Boot方法参见从0创建一个OS (二) boot_sector的"裸骨架"的编译、Boot部分

    ; ================================================================
    ; 文件名: boot_sect_memory_org.asm
    ; 本文件除开头的[org 0x7C00]外,其余与boot_sect_memory.asm一样
    ; 
    ; 本程序尝试打印一个"X",使用的方法为向AH传入0x0E,向AL传入待打印内容,即"X"
    ; 待打印内容定义为标签"the_secret"的形式
    ; ================================================================
    org 0x7c00
    
    mov ah, 0x0e
    
    mov al, "1"
    int 0x10
    
    mov al, [the_secret]
    int 0x10
    
    ; 在当前位置循环运行
    jmp $
    
    the_secret:
        db "X"
        
    times 510 - ($ - $$) db 0
    dw 0xAA55
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26

    实验结果

    在这里插入图片描述

    总结

    本节进行了诸多尝试,解释了boot sector中的变量存储方式,以后对boot sector的程序编写,首行一定要加上 org 0x7C00.

    boot sector虽然存储在磁盘的第一个512个字节范围,但是运行时被load到了0x7C00进行运行.

  • 相关阅读:
    20 C++设计模式之迭代器(Iterator)模式
    使用Kubernetes和Docker部署Java微服务
    Gateway基本配置:打开网络之门
    Recall:JS EventLoop
    OD华为机试 19
    工程建设行业智能供应链系统:优化产业链运作效率,实现全链路数字化建设
    C++初阶(类的访问权限以及封装+this指针+构造函数+析构函数+拷贝构造函数+参数列表+友元+内部类)
    SpringMvc 源码分析 (如何自定义视图 + 如何自定义异常) (十四)
    【Anaconda】Anaconda技巧汇总
    搭建FTP服务器备份vCenter
  • 原文地址:https://blog.csdn.net/humanof/article/details/127673879