鱼C论坛

 找回密码
 立即注册
查看: 2495|回复: 0

[学习笔记] X86汇编语言-从实模式到保护模式—笔记(7)

[复制链接]
发表于 2017-11-2 20:36:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 兰陵月 于 2017-12-5 21:55 编辑

第8章  硬盘和显卡的访问与控制

例程理解学习



1、加载程序,即主引导扇区程序;
2、用户程序,显示程序给定的文字信息。
(一)主引导扇区程序的运行
所有有关该行程序(或者某几行程序)的理解均写在该句之下。


app_lba_start equ 100;第1行
;声明常数(用户程序起始逻辑扇区号)
;常数的声明不会占用汇编地址。用软件查看编译后的文件内容,即可以看到其未占用地址。
;如下图。这是某源程序汇编后的文件内容,最左列为行号,第2列为汇编地址,第3列为二进制代码。
文中图片001.jpg
;第3行为声明常数的列,该列汇编地址处为空白;而第5列汇编地址为0x00000000,为起始处。
;这就说明了用equ声明常数不会占用汇编地址。编译之后,原来源程序所有有“app_lba_start”的
;地方全部用立即数100D代替了。
     ;程序第1行声明了1个常数100D,其作用是说明,将要加载的用户程序是存在硬盘逻辑扇区100开
;始的地方,要从硬盘逻辑扇区100开始的地方开始加载。这个数字是不随意设定的,为何是100呢,
;是因为等下我们编译好用户程序,写入硬盘时,正是从逻辑扇区100的地方开始写入的。因此,这
;里就对应地设置为100。第一次学习的时候,我百撕不得骑姐,后来学习到后面的时候,才知道,原
;本用户程序写入的地方就是逻辑扇区100开始的,才有了这里的100。
;如下图。就是图中这一步。在写入主引导扇区程序时,起始LBA扇区号为0,在写入用户程序时,起
;始LBA扇区号为100。
文中图片002.jpg

SECTION mbr align=16 vstart=0x7c00 ;第2行                                    
; 【“SECTION”或“SEGMENT”】 关键字作定义段用,表达方式为“SECTION 段名称”或
;“SEGMENT 段名称”。本行中段名称为:“mbr”。
;注意:一旦定义了一个段,则其后面的内容都属于该段,除非又出现了另一个段的定义。
;【“align=16”子句】表明该段是16字节对齐,“16字节对齐”的意思是,该段内的字节能够被16整
;除,如果该段字节数不足16字节,则缺少的内容用“00”补齐,如果该段字节数大于16字节且不能
;被整除,则不足16字节的最后一部分用“00”补齐。
;【“vstart=0x7c00”子句】表明该段内所有的地址都从“0x7c00”开始计算。本程序只有一个段,根据
;主引导程序的运行,程序总是先自动加载到物理地址“0x07c00”处开始运行的,也就是逻辑地址
;“0000:7c00”处(即不是从“0000:0000”的地方开始的),此处设置了从偏移地址“0x7c00”处开始,
;则在需要引用段内标号地址的地方就不用单独再加上“0x7c00”这个偏移量了。
;“vstart=0”表明该段内所有地址都从定义段的地方开始计算,而且从“0”开始计算。
;假如没有“vstart= ”子句,则该段内地址要从整个程序开始的地方开始计算。

mov ax,0  ;第3行
mov ss,ax  ; 第4行
mov sp,ax  ; 第5行
;第3、4、5行,设置主引导扇区程序的堆栈段和栈指针。
;执行完毕之后,SS:SP=0000:0000。

;下面第6~9行,计算用于加载用户程序的逻辑段地址。
;此时,CS、IP、SS、SP的值都已经明确,只有DS、ES的值还没明确。
;下面就开始计算要将用户程序加载到什么地址-逻辑地址表达方式。
;即“段地址:偏移地址”的方式,因此就要计算出段地址和偏移地址分别为多少?

mov ax,[cs:phy_base]  ; 第6行
mov dx,[cs:phy_base+0x02]  ; 第7行
mov bx,16  ; 第8行
div bx  ; 第9行
;下图中,源程序中标红线的第151行,定义了“phy_base dd 0x10000”。
文中图片003.jpg
;下图显示了标号“phy_base”处的存储示意情况。
文中图片004.jpg
;标号“phy_base”处是程序员设计好了的一个双字长度的物理地址。设计的时候就应考虑它能够被16
;整除,因此其最低4位为“0”,该32位物理地址被16整除了之后,得到的商就是逻辑地址中的段地
;址。第6~9行执行完毕之后,ax寄存器中为商,即为将要加载到的位置处的段地址,结果为0x1000。

mov ds,ax  ; 第10行
mov es,ax  ; 第11行                     
;第10行,将段地址给DS寄存器;第11行,将段地址给ES寄存器
;这样,当后续需要对被加载的用户程序部分的数据进行处理时,就可以使用DS和ES寄存器了。
;注意:用户程序在后续的加载操作中,将被加载到1000:0000开始的地方。这也是本程序设计的本意。
;以上部分其实都是做一些读取程序之前的相关准备工作,确保接下来的工作不出问题。
;下图为程序执行到现在时刻的内存状态示意图:
文中图片005.jpg

;以下读取程序的起始部分,即第一个扇区,为什么先读程序的起始部分,因为用户程序的头部有该程
;序的关键信息,特别是程序的长度数据,这样加载程序就知道要读取多少数据才能正确完整地加载用
;户程序了。


【未完待续,接-X86汇编语言-从实模式到保护模式—学习笔记(八)】

本帖被以下淘专辑推荐:

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-3-29 23:10

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表