前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux源码学习笔记day5 内存0地址处放的都是些什么玩意儿?

Linux源码学习笔记day5 内存0地址处放的都是些什么玩意儿?

作者头像
用户1072003
发布2023-02-23 17:07:52
3460
发布2023-02-23 17:07:52
举报
文章被收录于专栏:码上读书码上读书

上一次我们已经说到,操作系统的代码从硬盘复制到内存里了。

今天我们一起来看看,setup.s 都做了啥?

代码语言:javascript
复制
_start:
	mov %cs,%ax
	mov %ax,%ds
	mov %ax,%es
#
##print some message
#
	mov $0x03, %ah
	xor %bh, %bh
	int $0x10

	mov	%dx, %ds:0	# it from 0x90000.

这里又发起了一个10号中断, 上一次我们提到 13号是BIOS提供的读磁盘中断程序。0x10号中断调用显示服务的中断处理程序。

把寄存器ah赋值成0x03是为了给显示服务里,读取光标位置的子服务。

0x10号中断程序结束时,会在dx寄存器里存储光标的位置:

高八位 dh 存储行号

低八位 dl 存储列号

注意:计算机加电自检后会自动初始化为文字模式, 一屏25行,每行80列,一列一个字符。

接下来的mov 指令就是把光标位置存储在这个内存地址 给到ds:0的地址处。因为ds现在是0x9000, 所以0x90000里存的就是光标的位置了。

感觉中断和我们平时调用函数 有点类似,只不过用寄存器当作入参和返回值了。

接下来的一坨代码和上面逻辑差不多。调用中断程序获取点信息,存在内存里。

代码语言:javascript
复制
# Get memory size (extended mem, kB)

	mov	$0x88, %ah 
	int	$0x15
	mov	%ax, %ds:2

# Get video-card data:

	mov	$0x0f, %ah
	int	$0x10
	mov	%bx, %ds:4	# bh = display page
	mov	%ax, %ds:6	# al = video mode, ah = window width

# check for EGA/VGA and some config parameters

	mov	$0x12, %ah
	mov	$0x10, %bl
	int	$0x10
	mov	%ax, %ds:8
	mov	%bx, %ds:10
	mov	%cx, %ds:12

# Get hd0 data

	mov	$0x0000, %ax
	mov	%ax, %ds
	lds	%ds:4*0x41, %si
	mov	$INITSEG, %ax
	mov	%ax, %es
	mov	$0x0080, %di
	mov	$0x10, %cx
	rep
	movsb

# Get hd1 data

	mov	$0x0000, %ax
	mov	%ax, %ds
	lds	%ds:4*0x46, %si
	mov	$INITSEG, %ax
	mov	%ax, %es
	mov	$0x0090, %di
	mov	$0x10, %cx
	rep
	movsb

经过上面的代码处理,现在内存地址里存储的数据大致如下图:

熟悉的rep指令

后面马上就要轮到C语言上场了,汇编语言和C语言之间的数据交互,虽然也可以用变量的形式进行传递。对于这种大量的数据,双方约定了一个内存地址(类似一个公用银行卡号),我存你取。

存储好数据之后,用cli 关闭中断.

之所以关闭中断,是为了要写上我们自己的中断向量表,所以在这期间是不允许中断进来的。

接着看

代码语言:javascript
复制
# first we move the system to it's rightful place

	mov	$0x0000, %ax
	cld			# 'direction'=0, movs moves forward
do_move:
	mov	%ax, %es	# destination segment
	add	$0x1000, %ax
	cmp	$0x9000, %ax
	jz	end_move
	mov	%ax, %ds	# source segment
	sub	%di, %di
	sub	%si, %si
	mov 	$0x8000, %cx
	rep
	movsw
	jmp	do_move

# then we load the segment descriptors

最后 rep movsw 和之前从0x7c00复制到0x90000是一样的, 只不过这一次是从0x10000 到 0x90000的内容都复制到0的位置。

结果

现在内存布局大致是这个样子的:

可以看到从0到0x80000的这512K里是除了bootsect和setup的操作系统的代码。这么一来就把 之前启动时的 0x7c00那些内容都覆盖了。

0x7c00已经是前任了,感觉忘掉吧!

下一次,我们一起迎接新的篇章,模式转换

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2023-02-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 码上读书 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 熟悉的rep指令
  • 结果
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档