gdhyyanglang的专栏

前面我成功加载了第一个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

此时段寄存器cs、es、ds、gs等都为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条指令将改变寄存器ds、es。

<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

此时下一条指令为:将会跳出方法继续。方法中将会调用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

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

你并不一定会从此拥有更美好的人生,

gdhyyanglang的专栏

相关文章:

你感兴趣的文章:

标签云: