2 分析第一个OS

前面我成功加载了第一个OS,下面我将重点分析bochs加载OS时,寄存器都做了什么?


在使用选项6启动bochs的时候,在终端输入:<bochs:1>b 0x7c00,它表示在07c000地址处设置断点,因为引导扇区是从这里开始的。然后继续输入:<bochs:2>c,表示继续执行指令。完成这两条命令,将会看到终端命令窗口显示如下信息。


Nextat t=0

(0)[0x00000000fffffff0] f000:fff0 (unk. ctxt): jmp far f000:e05b ; ea5be000f0

<bochs:1>b 0x7c00

<bochs:2>c

00000003305i[BIOS] $Revision: 1.247 $ $Date: 2010/04/04 19:33:50 $

00000318057i[KBD ] reset-disable command received

00000442371i[VBIOS]VGABios $Id$

00000442442i[VGA ] VBE known Display Interface b0c0

00000442474i[VGA ] VBE known Display Interface b0c5

00000443143i[VBIOS]VBE Bios $Id$

00000600000i[XGUI] charmap update. Font Height is 16

00000760659i[BIOS] Starting rombios32

00000761138i[BIOS] Shutdown flag 0

00000761777i[BIOS] ram_size=0x02000000

00000762239i[BIOS] ram_end=32MB

00000802861i[BIOS] Found 1 cpu(s)

00000819037i[BIOS] bios_table_addr: 0x000fbc18 end=0x000fcc00

00000831660i[BIOS] bios_table_cur_addr: 0x000fbc18

00012943044i[BIOS] Booting from 0000:7c00

(0)Breakpoint 1, 0x00007c00 in ?? ()

Nextat t=12943105

(0)[0x0000000000007c00] 0000:7c00 (unk. ctxt): mov ax, cs ; 8cc8

<bochs:3>


可以看到,当我们在0x7c00设置断点时,代码执行到此处将会停止。同时终端命令窗口还显示了下一条命令,如:


(0)[0x0000000000007c00] 0000:7c00 (unk. ctxt): mov ax, cs ; 8cc8


注意[0x0000000000007c00],表示指令的地址,即加载程序的地方(还记得org07c00h吗?)。此时,可以输入命令,查看寄存器信息。(在《Orange's...》中使用dump_cpu,这个命令在bochs2.3.5以上版本中没有)


<bochs:3>info cpu

eax:0x0000aa55 43605

ecx:0x00090000 589824

edx:0x00000000 0

ebx:0x00000000 0

esp:0x0000ffd6 65494

ebp:0x00000000 0

esi:0x000e478c 935820

edi:0x0000ffac 65452

eip:0x00007c00

eflags0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf


可以看到eip指向0x7c00,表示执行从这个地方开始。这也是为什么代码清单要是用:org07c00h


<bochs:4>sreg

es:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

cs:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

ss:0x0000,dh=0x00009300, dl=0x0000ffff, valid=7

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

ds:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

fs:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

gs:0x0000,dh=0x00009300, dl=0x0000ffff, valid=1

Datasegment, base=0x00000000, limit=0x0000ffff, Read/Write, Accessed

ldtr:0x0000,dh=0x00008200, dl=0x0000ffff, valid=1

tr:0x0000,dh=0x00008b00, dl=0x0000ffff, valid=1

gdtr:base=0x000fb997,limit=0x30

idtr:base=0x00000000,limit=0x3ff


此时段寄存器csesdsgs等都为0。执行下一条指令(执行我编写的代码),看看寄存器状态。


<bochs:5>n

Nextat t=12943102

(0)[0x0000000000007c02] 0000:7c02 (unk. ctxt): mov ds, ax ; 8ed8

<bochs:6>r

eax:0x00000000 0

ecx:0x00090000 589824

edx:0x00000000 0

ebx:0x00000000 0

esp:0x0000ffd6 65494

ebp:0x00000000 0

esi:0x000e478c 935820

edi:0x0000ffac 65452

eip:0x00007c02

eflags0x00000082: id vip vif ac vm rf nt IOPL=0 of df if tf SF z


可以看到粗体标识的地方为执行:movax cs后的改变情况。同时下一条指令地址变为:[0x0000000000007c02],表示mov指令占用2个地址。后面的2条指令将改变寄存器dses


<bochs:7>n

Nextat t=12943103

(0)[0x0000000000007c04] 0000:7c04 (unk. ctxt): mov es, ax ; 8ec0

……

<bochs:8>n

Nextat t=12943104

(0)[0x0000000000007c06] 0000:7c06 (unk. ctxt):call .+2 (0x00007c0b) ; e80200


此时下一条指令为:call.+2 (0x00007c0b),其中0x00007c0b表示要跳转的地址。继续执行,n将会跳出方法继续。方法中将会调用int 10中断在显示器上显示字符。


<bochs:9>n

Next at t=12954683

(0)[0x0000000000007c09]0000:7c09 (unk. ctxt): jmp .-2 (0x00007c09)


从这句可以看出$表示当前地址。


<bochs:10> n

Next at t=12954684

(0) [0x0000000000007c09] 0000:7c09(unk. ctxt): jmp .-2 (0x00007c09) ; ebfe


因为跳转地址为执行语句地址,所以陷入无限循环。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值