前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Linux源码学习笔记day2 怎么复制到0x90000?

Linux源码学习笔记day2 怎么复制到0x90000?

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

上次我们学习到开机后会修改段寄存器ds为 0x07c0,方便之后利用这个段基址进行内存寻址。

这次我们主要学习以下几行代码:

代码语言:javascript
复制
.equ INITSEG, 0x9000

mov	$INITSEG, %ax	#将es段寄存器设置为0x900
mov	%ax, %es
mov	$256, %cx		
sub	%si, %si		
sub	%di, %di		
rep				
movsw

第一行先 定义常量INITSEG 为0x9000。

然后取出INITSEG的值 给到通用寄存器ax。

接着把ax给到了 段寄存器es。这时候es里的值就是0x9000了。

然后把立即数 256 给到了 通用寄存器 cx(一般cx 用作计数器)。

接下来2个 sub 指令,就是把 si 和 di都清零了。

现在ds, es, cx, si, di都有值了。

代码语言:javascript
复制
ds = 0x07c0
es = 0x9000
cx = 256
si = 0
di = 0

关键寄存器就变成了这样。

接下来的指令:

代码语言:javascript
复制
rep movsw

这里rep 是重复的意思,movsw是复制一个字。就是不断地复制一个字。


这里扩展一下:

  • 一个字节是8位
  • 一个字是16位

MOVS 是串指令里的串传送:

  • MOVSB 传送字符
  • MOVSW 传送字.
  • MOVSD 传送双字

一般来说 cx里有值,就意味要有循环了。

循环的次数:就是cx的值256。退出条件就是cx == 0

从哪儿复制到哪儿:从ds:si 复制到es:di,也就是0x7c00 复制到0x90000。

一次复制2个字节,复制256次 正好是复制了512个字节!也就是说将内存地址 0x7c00 处开始往后的 512 字节的数据,复制到 0x90000 处开始的后面 512 字节的地方

也就是这里的第二步:

接下来是一个跳转指令:

代码语言:javascript
复制
ljmp	$INITSEG, $go	#段间跳转,这里INITSEG指出跳转到的段地址,解释了cs的值为0x9000
go:	mov	%cs, %ax		#将ds,es,ss都设置成移动后代码所在的段处(0x9000)
	mov	%ax, %ds

作者那里是8086的指令里是jmpi,我看的这个是AT&T指令,这里是ljmp。

反正意思都是段间跳转。这里由于INITSEG是0x9000 所以就是要跳转到0x9000:go的地址。段基址要左移4位,所以最后要跳转到0x90000 + go的内存地址。

这个go: 在这里是一个标签(label),编译成机器码的时候会变成一个值,就是段内偏移地址。

这时候,假设偏移量是0x10,其实就是这一行代码

代码语言:javascript
复制
mov	%cs, %ax

所在的内存地址就是 0x90000 + 0x10 = 0x90010 CPU最终就会跳转到0x90010处。

下一次,我们一起看看go里面又发生了哪些”精彩“?

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

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档