操作系统实战45讲|01程序的运行过程、02几行汇编几行C

news2024/11/25 22:37:32

配置环境遇到的问题

virtualBox实现windows和Ubuntu之间的复制粘贴

1.修改设置,设置共享粘贴板为双向
在这里插入图片描述
或者在运行的虚拟机的窗口中进行设置
在这里插入图片描述
2.安装virtualbox增强功能
(1)直接联网安装 设备----安装增强功能
3.补充
windows中终端和文档复制的快捷键为ctrl+c,粘贴的快捷键为ctrl+v
Linux中终端复制的快捷键为ctrl+shift+c,粘贴的快捷键为ctrl+shift+v;文档中直接使用ctrl+c,ctrl+v;

设置清华大学开源软件镜像

01程序的运行过程:从代码到机器运行

gcc只是完成编译工作的驱动程序,它会根据编译流程分别调用预处理程序、编译程序、汇编程序、连接程序完成具体工作。
在这里插入图片描述
手动控制以上的编译流程:

gcc HelloWorld.c -E -o HelloWorld.i预处理:加入头文件,替换宏
gcc HelloWorld.c -S -c -o HelloWorld.s编译:包含预处理,讲C程序转换成汇编程序
gcc HelloWorld.c -c -o HelloWorld.o汇编:包含预处理和编译,将汇编程序转换成可连接的二进制程序
gcc HelloWorld.c -o HelloWorld链接:包含以上所有操作,将可链接的二进制程序和其他别的库链接在一起,形成可执行的程序文件。

计算机必须具备五大基本组件:

  1. 装载程序和数据的输入设备
  2. 记住程序和数据的存储器
  3. 完成数据加工处理的运算器
  4. 控制程序执行的控制器
  5. 显示处理结果的输出设备

将HelloWorld程序装入原型计算机

可以通过gcc -c -S HelloWorld得到汇编代码。用objdump -d HelloWorld程序得到HelloWorld.dump
在这里插入图片描述

以上图中,分成四列:第一列为地址;第二列为十六进制,表示真正装入机器中的代码数据;第三列是对应的汇编代码;第四列是相关代码的注释。这是 x86_64 体系的代码,由此可以看出 x86 CPU 是变长指令集

思考题

为了实现 C 语言中函数的调用和返回功能,CPU 实现了函数调用和返回指令,即上图汇编代码中的“call”,“ret”指令,请你思考一下:call 和 ret 指令在逻辑上执行的操作是怎样的呢?
思考题: 首先假设CPU执行指令是顺序执行的,那么程序的调用需要考虑几个问题:
1,call指令要执行的代码在哪?也就是被调用函数的第一条指令所在的内存地址
2,被调用函数执行完之后,返回哪个位置继续执行?
只要解决上面这两个问题,那么函数调用时指令的间的跳转就迎刃而解了。

针对第一个问题,在gcc编译完成之后,函数对应的指令序列所在的位置就已经确定了,因此这是编译阶段需要考虑的问题

至于第二个问题,在执行完call指令的同时,需要将call指令下面一条指令的地址保存到栈内存中,同时更新%rsp寄存器指向的位置,然后就可以开始执行被调函数的指令序列,执行完毕后,由ret指令从rsp中获取栈顶的returnadress地址,然后跳转到call的下一条指令继续执行。

02几行汇编几行C

PC机的引导流程

只要PC机上安装了Ubuntu Linux操作系统,GRUB就已经存在了。写Hello OS之前,先搞清楚Hello OS的引导流程,如下图所示:
在这里插入图片描述
简单解释一下,PC 机 BIOS 固件是固化在 PC 机主板上的 ROM 芯片中的,掉电也能保存,PC 机上电后的第一条指令就是 BIOS 固件中的,它负责检测和初始化 CPU、内存及主板平台,然后加载引导设备(大概率是硬盘)中的第一个扇区数据,到 0x7c00 地址开始的内存空间,再接着跳转到 0x7c00 处执行指令,在我们这里的情况下就是 GRUB 引导程序。

Hello OS引导汇编代码

C作为通用的高级语言,不能直接操作特定的硬件,而且C语言的函数调用、函数传参都需要用栈。栈由特定的栈寄存器指向,所以先用汇编代码处理好这些C语言的工作环境。

MBT_HDR_FLAGS EQU 0x00010003
MBT_HDR_MAGIC EQU 0x1BADB002 ;多引导协议头魔数
MBT_HDR2_MAGIC EQU 0xe85250d6 ;第二版多引导协议头魔数
global _start ;导出_start符号
extern main ;导入外部的main函数符号
[section .start.text] ;定义.start.text代码节
[bits 32] ;汇编成32位代码
_start:
jmp _entry
ALIGN 8
mbt_hdr:
dd MBT_HDR_MAGIC
dd MBT_HDR_FLAGS
dd -(MBT_HDR_MAGIC+MBT_HDR_FLAGS)
dd mbt_hdr
dd _start
dd 0
dd 0
dd _entry
;以上是GRUB所需要的头
ALIGN 8
mbt2_hdr:
DD MBT_HDR2_MAGIC
DD 0
DD mbt2_hdr_end - mbt2_hdr
DD -(MBT_HDR2_MAGIC + 0 + (mbt2_hdr_end - mbt2_hdr))
DW 2, 0
DD 24
DD mbt2_hdr
DD _start
DD 0
DD 0
DW 3, 0
DD 12
DD _entry
DD 0
DW 0, 0
DD 8
mbt2_hdr_end:
;以上是GRUB2所需要的头
;包含两个头是为了同时兼容GRUB、GRUB2
ALIGN 8
_entry:
;关中断
cli
;关不可屏蔽中断
in al, 0x70
or al, 0x80
out 0x70,al
;重新加载GDT
lgdt [GDT_PTR]
jmp dword 0x8 :_32bits_mode
_32bits_mode:
;下面初始化C语言可能会用到的寄存器
mov ax, 0x10
mov ds, ax
mov ss, ax
mov es, ax
mov fs, ax
mov gs, ax
xor eax,eax
xor ebx,ebx
xor ecx,ecx
xor edx,edx
xor edi,edi
xor esi,esi
xor ebp,ebp
xor esp,esp
;初始化栈,C语言需要栈才能工作
mov esp,0x9000
;调用C语言函数main
call main
;让CPU停止执行指令
halt_step:
halt
jmp halt_step
GDT_START:
knull_dsc: dq 0
kcode_dsc: dq 0x00cf9e000000ffff
kdata_dsc: dq 0x00cf92000000ffff
k16cd_dsc: dq 0x00009e000000ffff
k16da_dsc: dq 0x000092000000ffff
GDT_END:
GDT_PTR:
GDTLEN dw GDT_END-GDT_START-1
GDTBASE dd GDT_START
  1. 代码 1 ~ 40 行,用汇编定义的 GRUB 的多引导协议头,其实就是一定格式的数据,我们的 Hello OS 是用 GRUB 引导的,当然要遵循 GRUB 的多引导协议标准,让 GRUB 能识别我们的 Hello OS。之所以有两个引导头,是为了兼容 GRUB1 和 GRUB2。
  2. 代码 44 ~ 52 行,关掉中断,设定 CPU 的工作模式。
  3. 代码 54 ~ 73 行,初始化 CPU 的寄存器和 C 语言的运行环境。
  4. 代码 78~87 行,GDT_START 开始的,是 CPU 工作模式所需要的数据。

Hello Os的主函数

上面的汇编代码调用了main函数,但是在代码中并没有看到函数体,而是从外部导入一个符号。那是因为这个函数是用C语言写的(main.c中),最终它们分别由nasm和gcc编译成可链接模块,由LD链接器接在一起,形成可以执行的程序文件:

#include "vgastr.h"
void main
{
	printf("Hello OS!");
	return ;
}

这不是应用程序的main函数而是Hello OS的main函数。
其中的printf也不是应用程序库中的那个printf,而是需要自己实现。

控制计算机屏幕

计算机屏幕显示往往是显卡的输出,显卡有很多形式:集成在主板的叫集显,做在CPU芯片内的叫核显,独立存在通过PCIE接口连接的叫独显,性能和价格依次上升。
独显的高性能是游戏玩家们所钟爱的,3D 图形显示往往要涉及顶点处理、多边形的生成和变换、纹理、着色、打光、栅格化等。而这些任务的计算量超级大,所以独显往往有自己的 RAM、多达几百个运算核心的处理器。因此独显不仅仅是可以显示图像,而且可以执行大规模并行计算,比如“挖矿”。

要在屏幕上显示字符,就要编程操作显卡。
其实无论我们 PC 上是什么显卡,它们都支持一种叫 VESA 的标准,这种标准下有两种工作模式:字符模式和图形模式。显卡们为了兼容这种标准,不得不自己提供一种叫 VGABIOS 的固件程序。

显卡的字符模式的工作细节。它把屏幕分成 24 行,每行 80 个字符,把这(24*80)个位置映射到以 0xb8000 地址开始的内存中,每两个字节对应一个字符,其中一个字节是字符的 ASCII 码,另一个字节为字符的颜色值。如下图所示:
在这里插入图片描述
开始编写代码


//彭东 @ 2021.01.09
void _strwrite(char* string)
{
  char* p_strdst = (char*)(0xb8000);//指向显存的开始地址
  while (*string)
  {
    *p_strdst = *string++;
    p_strdst += 2;
  }
  return;
}

void printf(char* fmt, ...)
{
  _strwrite(fmt);
  return;
}

printf 函数直接调用了 _strwrite 函数,而 _strwrite 函数正是将字符串里每个字符依次定入到 0xb8000 地址开始的显存中,而 p_strdst 每次加 2,这也是为了跳过字符的颜色信息的空间。

编译和安装Hello OS

make

在软件开发中,make是一个工具程序,读取一个叫“makefile”的文件,也是一种文本文件,这个文件中写好了构建软件的规则,make可以根据这个规则自动化构建软件。
makefile文件中规则是这样的:
首先有一个或者多个构建目标称为target;目标后面紧跟着用于构建该目标所需要的文件,目标下面是构建该目标所需要的命令以及参数。
与此同时也会检查文件的依赖关系,如果需要的话,会调用一些外部软件完成任务。
第一次构建目标后,下一次执行make时,会根据该目标所依赖 的文件是否更新决定是否重新编译该目标。如果依赖的文件没有更新且该目标存在,那么便不会构建该目标。这种特性非常有利于编译程序源代码。


CC = gcc #定义一个宏CC 等于gcc
CFLAGS = -c #定义一个宏 CFLAGS 等于-c
OBJS_FILE = file.o file1.o file2.o file3.o file4.o #定义一个宏
.PHONY : all everything #定义两个伪目标all、everything
all:everything #伪目标all依赖于伪目标everything
everything :$(OBJS_FILE) #伪目标everything依赖于OBJS_FILE,而OBJS_FILE是宏会被
#替换成file.o file1.o file2.o file3.o file4.o
%.o : %.c
   $(CC) $(CFLAGS) -o $@ $<

make 规定“#”后面为注释,make 处理 makefile 时会自动丢弃。
makefile 中可以定义宏,方法是在一个字符串后跟一个“=”或者“:=”符号,引用宏时要用“ ( 宏名 ) ”,宏最终会在宏出现的地方替换成相应的字符串,例如: (宏名)”,宏最终会在宏出现的地方替换成相应的字符串,例如: (宏名),宏最终会在宏出现的地方替换成相应的字符串,例如:(CC) 会被替换成 gcc, ( O B J S F I L E ) 会被替换成 f i l e . o f i l e 1. o f i l e 2. o f i l e 3. o f i l e 4. o 。 . P H O N Y 在 m a k e f i l e 中表示定义伪目标。所谓伪目标,就是它不代表一个真正的文件名,在执行 m a k e 时可以指定这个目标来执行其所在规则定义的命令。但是伪目标可以依赖于另一个伪目标或者文件,例如: a l l 依赖于 e v e r y t h i n g , e v e r y t h i n g 最终依赖于 f i l e . c f i l e 1. c f i l e 2. c f i l e 3. c f i l e 4. c 。虽然我们会发现, e v e r y t h i n g 下面并没有相关的执行命令,但是下面有个通用规则:“ ( OBJS_FILE) 会被替换成 file.o file1.o file2.o file3.o file4.o。 .PHONY 在 makefile 中表示定义伪目标。所谓伪目标,就是它不代表一个真正的文件名,在执行 make 时可以指定这个目标来执行其所在规则定义的命令。但是伪目标可以依赖于另一个伪目标或者文件,例如:all 依赖于 everything,everything 最终依赖于 file.c file1.c file2.c file3.c file4.c。 虽然我们会发现,everything 下面并没有相关的执行命令,但是下面有个通用规则:“%.o : %.c”。其中的“%”表示通配符,表示所有以“.o”结尾的文件依赖于所有以“.c”结尾的文件。例如:file.c、file1.c、file2.c、file3.c、file4.c,通过这个通用规则会自动转换为依赖关系:file.o: file.c、file1.o: file1.c、file2.o: file2.c、file3.o: file3.c、file4.o: file4.c。然后,针对这些依赖关系,分别会执行: (OBJSFILE)会被替换成file.ofile1.ofile2.ofile3.ofile4.o.PHONYmakefile中表示定义伪目标。所谓伪目标,就是它不代表一个真正的文件名,在执行make时可以指定这个目标来执行其所在规则定义的命令。但是伪目标可以依赖于另一个伪目标或者文件,例如:all依赖于everythingeverything最终依赖于file.cfile1.cfile2.cfile3.cfile4.c。虽然我们会发现,everything下面并没有相关的执行命令,但是下面有个通用规则:(CC) $(CFLAGS) -o $@ $< 命令,当然最终会转换为:gcc –c –o xxxx.o xxxx.c,这里的“xxxx”表示一个具体的文件名。

编译

在这里插入图片描述

安装Hello OS

我们就会得到 Hello OS.bin 文件,但是我们还要让 GRUB 能够找到它,才能在计算机启动时加载它。这个过程我们称为安装

遇到的问题以及参考的博客

1.在修改/ /etc/default/grub这个文件的时候一直修改不成功,因为这是一个只读文件,即使使用了sudo命令还是修改失败。需要先修改这个文件的属性将其变为一个可修改的文件,修改完之后在变为只读文件。修改方式如下:

sudo chmod 666 /etc/default/grub 或者
sudo chmod ugo+w /etc/default/grub 
# 变成只读
sudo chmod 444 /etc/default/grub 或者
sudo chmod ugo-w /etc/default/grub 

2.参考博客:HelloOS的编译和安装
3.虚拟机联网的方式(在进行XFTP连接虚拟机时需要将虚拟机的联网方式改成桥接模式)
4.设置开机进入grub界面的方法

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/724770.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

flashplayer timeout 15s

Error: Error #1502: 脚本的执行时间已经超过了 15 秒的默认超时设置。at mx.core::Container/http://www.adobe.com/2006/flex/mx/internal::getScrollableRect()[C:\autobuild\3.2.0\frameworks\projects\framework\src\mx\core\Container.as:4209]at mx.core::Container/cre…

自然语言处理:了解循环神经网络RNN及其变种长短期记忆网络(LSTM)、门控循环单元(GRU)、双向RNN

文章目录 一、RNN二、GRU三、LSTM四、GRU vs LSTM五、双向RNN 一、RNN 递归神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一种具有时间序列依赖性的人工神经网络结构。其主要原理是在传统神经网络的基础上引入了循环连接&#xff0c;允许信息在…

基于51单片机温湿度-烟雾-一氧化碳-蓝牙-风扇的设计与实现

功能介绍 以51单片机作为主控系统&#xff1b;LCD1602液晶显示屏来显示显示测得的值&#xff1b;一氧化碳感应一氧化碳的数值&#xff1b;通过烟雾传感器获取前的烟雾值&#xff1b;通过DHT11温湿度传感器来获取当前的温湿度&#xff1b;当温度或烟雾高于阈值打开风扇&#xff…

折叠屏手机再添新功能?OPPOColorOS14发布,打通 App 和终端互联

近年来&#xff0c;多终端互联互通已经成为数码产品的发展趋势&#xff0c;各家手机品牌也在不断提升相关功能。 根据数码博主 数码闲聊站的爆料&#xff0c;OPPO即将发布ColorOS 14&#xff0c;并特别提供了针对折叠屏手机的Fold系统。该系统在横屏模式下对自带应用进行了更好…

工程项目综合管理系统拥有哪些功能,你真的了解吗?

在建筑工程行业中&#xff0c;项目的管理是一项复杂而又关键的任务。为了提高项目管理的效率和准确性&#xff0c;许多企业开始采用信息化系统进行精细化管理。因此&#xff0c;建立一套完善的工程项目管理系统&#xff0c;成为了建筑工程管理的必要条件之一。这种系统结合了工…

pytest+yaml实现接口自动化框架

目录 前言 项目结构设计 yaml格式的用例 运行用例 总结&#xff1a; 前言 httprunner 用 yaml 文件实现接口自动化框架很好用&#xff0c;最近在看 pytest 框架&#xff0c;于是参考 httprunner的用例格式&#xff0c;写了一个差不多的 pytest 版的简易框架 项目结构设计…

【PowerDesigner】数据库建模工具记录

导入格式 最终效果 执行语句 工具(tool) -> 其他记录 执行脚本 快捷键&#xff1a;CtrlShiftX 工具(tool) -》Execute Commands -》 Edit/Run Script 导入脚本 快捷键&#xff1a;Ctrl R 数据库-》Update Model from Database 显示首选项 ODBC 数据源管理程序 Powerd…

Istio 流量管理 serviceEntry 出口流量管理

无论是vs还是dr这些都是入口的流量。对于pod来说也会有出去的流量的。 除了对进来的流量做有效的控制之外&#xff0c;其实也可以控制出去的流量。istio-egress是出口网关&#xff0c;pod出去的时候要经过egress-gateway到达外界的某个终端。 hosts: - www.baidu.com 这个是p…

腾讯云对象存储联合DataBend云数仓打通数据湖和数据仓库

随着数字化进程不断深入&#xff0c;数据呈大规模、多样性的爆发式增长。为满足更多样、更复杂的业务数据处理分析的诉求&#xff0c;湖仓一体应运而生。在Gartner发布的《Hype Cycle for Data Management 2021》中&#xff0c;湖仓一体&#xff08;Lake house&#xff09;首次…

Linux之CentOS_7.9卸载MySQL_5.7全过程实操手册

前言&#xff1a;接以上&#xff0c;前面记录了Windows和Linux环境的MySQL部署&#xff0c;那我们既然都部署完成验证测试那就来个卸载记录吧&#xff0c;便于闭环收尾。 环境&#xff1a; 1、CentOS-7.9-x86_64-DVD-2009.iso 2、MySQL-5.7.42-linux-glibc2.12-x86_641、关闭…

软件测试工程师生存手册

以前做传统行业时&#xff0c;从来没担忧过自己会因为什么事被干掉&#xff0c;因为觉得自己工资低。培训转行跳到IT互联网公司后&#xff0c;这种担忧从未消失过。 互联网公司发展迭代非常迅速。今天通过切身的感受来聊一聊&#xff0c;作为一名测试工程师&#xff0c;如何才能…

OutOfMemoryError: unable to create new native thread.

在java应用中&#xff0c;有时候会出现这样的错误&#xff1a;OutOfMemoryError: unable to create new native thread.现象1. 这种怪事是因为JVM已经被系统分配了大量的内存(比如1.5G)&#xff0c;并且它至少要占用可用内存的一半&#xff1b;2. 在线程个数很多的情况下&#…

电脑便签怎么嵌入桌面使其不可移动呢?

很多人在使用电脑便签的时候&#xff0c;为了更方便地查看和记录事情&#xff0c;经常会有一种需求&#xff1a;将电脑便签固定在桌面底层&#xff0c;也就是嵌入桌面&#xff0c;并且让他不可移动。要想实现这种效果的话&#xff0c;应该如何设置才可以呢&#xff1f;以Window…

kettle/spoon工具的表输入/输出组件更新数据很慢

看了很多关于表输出速度慢的博客感觉有两条对我有作用。 我的问题是表输出&#xff08;insert&#xff09;速度很快&#xff0c;但是插入/更新组件的速度特别忙。 表输出速度慢 mysql表输出的时候出现减速的原因可能是因为网络链接的属性设置 在数据库连接里添加参数&#xf…

ModaHub魔搭社区:如何安装、部署和使用 Milvus Lite?

目录 如何安装、部署和使用 Milvus Lite? 总结 如何安装、部署和使用 Milvus Lite? 准备工作 在正式安装 Milvus Lite 以前&#xff0c;需要做足以下准备&#xff1a; 安装 Python 3.7 或更高版本。 使用下述任何一个经过验证的操作系统&#xff1a;Ubuntu > 20.04 …

【MySQL入门到精通-黑马程序员】MySQL基础篇-概述及MySQL环境配置

文章目录 前言一、MySQL概述1.1 数据库相关概念1.2 MySQL数据库 二、数据模型三、总结 前言 本专栏文章为观看黑马程序员《MySQL入门到精通》所做笔记&#xff0c;课程地址在这。如有侵权&#xff0c;立即删除。 一、MySQL概述 1.1 数据库相关概念 数据库&#xff08;DataBas…

FreeRTOS实时操作系统(十一)队列集

系列文章目录 文章目录 系列文章目录队列集简介相关API函数队列集创建函数队列集中移除函数队列集中获取有消息的队列 实验测试&#xff1a; 队列集简介 队列只允许传递一种数据类型&#xff0c;队列集可以传递多种消息。 作用&#xff1a;用于对多个队列或信号量进行“监听”…

PicoNeo neo入门教程2 SDK

目前在使用的是Unity XR SDK V2.x, 当前版本2.2.0版本 查看文档&#xff0c;有更新日志。 api接口&#xff1a;API 接口函数 - PICO 开发者平台

Pytorch TensorRT 安装使用流程

1.安装GPU驱动与Cudnn&#xff08;注意版本对应&#xff09; 2.安装TensorRT 安装流程1 安装流程2 3. 权值.pth文件转为Onnx 3.Onnx 文件本地化 .engine 文件&#xff08;与本机算力有关&#xff09; 执行命令&#xff1a; trtexec --onnx./resnet.onnx --saveEngineresn…

MongoDB【MongoDB应用实战】(四)-全面详解(学习总结---从入门到深化)

目录 MongoDB应用实战 多键索引 多键索引用于为数组中的元素创建索引 先创建集合inventory&#xff0c;使用下面的数据来创建多键索引 [{ _id: 5, type: "food", item: "aaa", ratings:[ 5, 8, 9 ] }, { _id: 6, type: "food", item: "b…