Linux0.11——第二回 从0x7c00到0x90000
上一讲,讲了CPU执行操作系统的最开始的两行代码:
mov ax, 0x07c0
mov ds, ax
这两行代码将数据段寄存器 ds 的值变成了 0x07c0,方便之后访问内存时,利用这个段基址进行寻址。
接下来的代码:
mov ax,0x9000
mov es,ax
mov cx,#256
sub si,si
sub di,di
rep movw
此时,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个字节,
根据这行指令,自然就会引出以下三个问题:
- 重复执行多少次呢?答案是 cx 寄存器中的值,也就是 256 次。
- 从哪复制到哪呢?答案是从 ds:si 处复制到 es:di 处,也就是从 0x7c00 复制到 0x90000。
- 一次复制多少呢?刚刚说过了,复制一个字 16 位,也就是两个字节。那么。一共复制 256 次的两个字节,其实就是复制 512 个字节。
总结一下就是,将启动区的512字节,又把它移动到0x90000处开始的512字节处,也就是下面的样子:

我理解的就是:0x7c00这个地址位置比较靠前,为了操作系统的代码不被覆盖,把它先移动到比较靠后的位置。现在操作系统最开始的代码位于0x90000处了,再往后看代码会发现这是一条跳转指令了:
jmpi go, 0x9000
go: mov ax,csmov ds,axmov es,ax
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地址处。然后接着运行。
相关文章:
Linux0.11——第二回 从0x7c00到0x90000
上一讲,讲了CPU执行操作系统的最开始的两行代码: mov ax, 0x07c0 mov ds, ax这两行代码将数据段寄存器 ds 的值变成了 0x07c0,方便之后访问内存时,利用这个段基址进行寻址。 接下来的代码: mov ax,0x9000 mov es,ax…...
封装了一个中间放大效果的iOS轮播视图
效果图 计算逻辑 设定在中间展示的size,即正常size,然后设置水平和竖直方向上的margin, 在view的origin和scrollView的contentoffset相等的时候,即 视图处在正中间的时候,最大,然后通过计算其他视图的origin和scrollV…...
趣解设计模式之《小王的糖果售卖机》
〇、小故事 小王最近一直在寻找商机,他发现商场儿童乐园或者中小学校周围,会有很多小朋友喜欢吃糖果,那么他想设计一款糖果售卖机,让后将这些糖果售卖机布置到商场和学校旁边,这样就能获得源源不断的收益了。 想到这里…...
Redis 哨兵模式模式搭建教程
一、介绍 本文实战搭建一主两从三哨兵,通过使用哨兵模式,可以有效避免某台服务器的 Redis 挂掉出现的不可用问题,保障系统的高可用。 本文通过虚拟机搭建的三台 Centos7 服务器进行测试,使用的 Redis 版本为 6.25。 二、准备环…...
41. Linux系统配置FTP服务器并在QT中使用QFtp实现文件上传
1. 说明 这篇博客主要记录一些在Linux系统中搭建FTP服务器时踩过的一些坑,以及在使用QFtp上传文件时需要注意的问题。 2. FTP环境搭建 在linux系统中,需要安装vsftpd,可以在终端中输入下面的命令进行安装: sudo apt-get install vsftpd使用上述命令安装后,系统中会有一…...
【新版】系统架构设计师 - 案例分析 - 架构设计<架构风格和质量属性>
个人总结,仅供参考,欢迎加好友一起讨论 文章目录 架构 - 案例分析 - 架构设计<架构风格和质量属性>例题1例题2例题3例题4例题5例题6 架构 - 案例分析 - 架构设计<架构风格和质量属性> 例题1 某软件公司为…...
C++ - 红黑树 介绍 和 实现
前言 前面 学习了 AVL树,AVL树虽然在 查找方面始终拥有 O(log N )的极高效率,但是,AVL 树在插入 ,删除等等 修改的操作当中非常的麻烦,尤其是 删除操作,在实现当中细节非常多,在实现上非常难掌控…...
【蓝桥杯选拔赛真题62】Scratch判断小球 少儿编程scratch图形化编程 蓝桥杯选拔赛真题解析
目录 scratch判断小球 一、题目要求 编程实现 二、案例分析 1、角色分析...
Spring面试题15:Spring支持几种bean的作用域?singleton、prototype、request的区别是什么?
该文章专注于面试,面试只要回答关键点即可,不需要对框架有非常深入的回答,如果你想应付面试,是足够了,抓住关键点 面试官:Spring支持几种bean的作用域? Spring支持以下几种Bean的作用域: Singleton(单例):这是Spring默认的作用域。使用@Scope(“singleton”)注解或…...
Spring Boot中Tomcat服务器参数解析及高并发控制
Spring Boot中Tomcat服务器参数解析及高并发控制 Spring Boot 集成了多种服务器,默认使用了Tomcat 服务器。在高并发情况下,合理地配置 Tomcat 服务器参数对于控制请求量和提高系统的稳定性至关重要。本文将解释 Spring Boot 中涉及 Tomcat 服务器的一些…...
Python 运行代码
一、Python运行代码 可以使用三种方式运行Python,如下: 1、交互式 通过命令行窗口进入 Python 并开始在交互式解释器中开始编写 Python 代码 2、命令行脚本 可以把代码放到文件中,通过python 文件名.py命令执行代码,如下ÿ…...
【ROS入门】使用 ROS 话题(Topic)机制实现消息发布与订阅及launch文件的封装
文章结构 任务要求话题模型实现步骤创建工作空间并初始化创建功能包并添加依赖创建发布者代码(C)创建订阅方代码(C)配置CMakeLists.txt执行启动roscore编译启动发布和订阅节点 launch封装执行 任务要求 使用 ROS 话题(Topic)机制…...
【企业级SpringBoot单体项目模板 】——Mybatis-plus自动代码生成
😜作 者:是江迪呀✒️本文关键词:SpringBoot项目模版、企业级、模版☀️每日 一言:我们之所以这样认为,是因为他们这样说。他们之所以那样说,是因为他们想让我们那样认为。所以实践才是检验真理…...
怒刷LeetCode的第14天(Java版)
目录 第一题 题目来源 题目内容 解决方法 方法一:动态规划 方法二:栈 方法三:双指针 第二题 题目来源 题目内容 解决方法 方法一:二分查找 方法二:线性扫描 方法三:递归 第三题 题目来源 …...
c语言 static
1、静态局部变量在程序加载时初始化,静态局部变量的初始值写入到了data段: 如下代码test_symbol.c int f() {static int x 0;return x; }int g() {static int x 9;return x; }使用命令gcc -c test_symbol.c -o test_symbol 编译 使用命令 readelf -a …...
java基础3
输入一个班学生的成绩,先显示所有及格的成绩,再显示所有不及格的成绩,最后显示及格人数和不及格人数 import java.util.Scanner; public class Hello{public static void main(String [] args) {int SIZE5;double grade[] new double[SIZE]…...
LeetCode 1194.锦标赛优胜者
数据准备 Create table If Not Exists Players (player_id int, group_id int); Create table If Not Exists Matches (match_id int, first_player int, second_player int, first_score int, second_score int); Truncate table Players; insert into Players (player_id, g…...
多旋翼无人机组合导航系统-多源信息融合算法(Matlab代码实现)
💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…...
如何用ArkUI实现一个加入购物车效果?
关键词:ArkUI的动效能力,动效开发,ArkUI动画 我们在购买商品时,往往习惯将商品先加入购物车,然后在购物车里确认后再下订单,这是一个典型的访问者模式。对于这个高频场景,增添一些动效可以增加a…...
ChatGLM GPT原理介绍
图解GPT 除了BERT以外,另一个预训练模型GPT也给NLP领域带来了不少轰动,本节也对GPT做一个详细的讲解。 OpenAI提出的GPT-2模型(https://openai.com/blog/better-language-models/) 能够写出连贯并且高质量的文章,比之前语言模型效果好很多。GPT-2是基于Transformer搭建的,相…...
Vim 调用外部命令学习笔记
Vim 外部命令集成完全指南 文章目录 Vim 外部命令集成完全指南核心概念理解命令语法解析语法对比 常用外部命令详解文本排序与去重文本筛选与搜索高级 grep 搜索技巧文本替换与编辑字符处理高级文本处理编程语言处理其他实用命令 范围操作示例指定行范围处理复合命令示例 实用技…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
centos 7 部署awstats 网站访问检测
一、基础环境准备(两种安装方式都要做) bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats࿰…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
反射获取方法和属性
Java反射获取方法 在Java中,反射(Reflection)是一种强大的机制,允许程序在运行时访问和操作类的内部属性和方法。通过反射,可以动态地创建对象、调用方法、改变属性值,这在很多Java框架中如Spring和Hiberna…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
Java数值运算常见陷阱与规避方法
整数除法中的舍入问题 问题现象 当开发者预期进行浮点除法却误用整数除法时,会出现小数部分被截断的情况。典型错误模式如下: void process(int value) {double half = value / 2; // 整数除法导致截断// 使用half变量 }此时...
MyBatis中关于缓存的理解
MyBatis缓存 MyBatis系统当中默认定义两级缓存:一级缓存、二级缓存 默认情况下,只有一级缓存开启(sqlSession级别的缓存)二级缓存需要手动开启配置,需要局域namespace级别的缓存 一级缓存(本地缓存&#…...

