学习笔记
《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f
代码运行
零、从加载程序mbr到内核程序core
<bochs:1> s
Next at t=1
(0) [0x0000000fe05b] f000:e05b (unk. ctxt): xor ax, ax
<bochs:2> b 0x7c00
<bochs:3> c
<bochs:4> b 0x7d38
<bochs:5> c
(0) Breakpoint 2, 0x0000000000007d38 in ?? ()
Next at t=17414844
(0) [0x000000007d38] 0010:0000000000000138 (unk. ctxt): jmpf ds:[edi+16]
<bochs:6> s
Next at t=17414845
(0) [0x000000040df1] 0038:0000000000000399 (unk. ctxt): mov ecx, 0x00000030
一、creg :查看 CR3寄存器 的值
1、从bochs
里面读出选择子;
2、从文件c16_core.lst
里面找出偏移量;
3、按照如下的顺序执行bochs
指令;
<bochs:6> s
Next at t=17414845
(0) [0x000000040df1] 0038:0000000000000399 (unk. ctxt): mov ecx, 0x00000030
<bochs:7> b 0x0038:0x00493
<bochs:8> c
(0) Breakpoint 3, 0x0000000000040eeb in ?? ()
Next at t=17427260
(0) [0x000000040eeb] 0038:0000000000000493 (unk. ctxt): mov eax, 0x00020000
<bochs:9> b 0x0038:0x04A3
<bochs:10> c
(0) Breakpoint 4, 0x0000000000040efb in ?? ()
Next at t=17427264
(0) [0x000000040efb] 0038:00000000000004a3 (unk. ctxt): mov cr0, eax
<bochs:11> s
Next at t=17427265
(0) [0x000000040efe] 0038:00000000000004a6 (unk. ctxt): mov ebx, 0xfffff000
4、CR3寄存器,此时已写入了物理地址,使用指令creg
,查看其内容;
<bochs:12> creg
CR0=0xe0000011: PG CD NW ac wp ne ET ts em mp PE
CR2=page fault laddr=0x0000000000000000
CR3=0x000000020000
PCD=page-level cache disable=0
PWT=page-level write-through=0
CR4=0x00000000: pke smap smep osxsave pcid fsgsbase smx vmx osxmmexcpt umip osfxsr pce pge mce pae pse de tsd pvi vme
CR8: 0x0
EFER=0x00000000: ffxsr nxe lma lme sce
<bochs:13>
- CR0寄存器的 PE 以及PG位 均是大写,表示值为1;
-
CR3寄存器的值是 当前任务 页目录表 的 物理地址,
CR3=0x000000020000
二、page : 查看线性地址对应的物理页信息
1、 由.lst
文件可以读出偏移量0x04A3
995 000004A3 0F22C0 mov cr0,eax ;开启分页机制
2、page指令
需要在开启分页机制之后才能奏效;
3、那么至少需要bochs
执行到 b 0x0038:0x04A3
并且s
,确保mov cr0, eax
被执行完毕!
<bochs:7> b 0x0038:0x4A3
<bochs:8> c
(0) Breakpoint 3, 0x0000000000040efb in ?? ()
Next at t=17427264
(0) [0x000000040efb] 0038:00000000000004a3 (unk. ctxt): mov cr0, eax ; 0f22c0
<bochs:9> s
Next at t=17427265
(0) [0x000000040efe] 0038:00000000000004a6 (unk. ctxt): mov ebx, 0xfffff000 ; bb00f0ffff
4、page 指令查看 与线性地址对应的物理页信息
<bochs:10> page 0x7e08
PDE: 0x0000000000021003 ps a pcd pwt S W P
PTE: 0x0000000000007003 g pat d a pcd pwt S W P
linear page 0x0000000000007000 maps to physical page 0x000000007000
<bochs:11>
-
page 0x7e08
中的0x7e08
是线性地址; -
PDE: 0x0000000000021003
,页目录表表项,内容是0x21003
(最后的3
是页属性),即,页表的物理地址是0x21000
; -
PTE: 0x0000000000007003
,页表表项,内容是0x7003
(最后的3
是页属性),即,物理页的物理地址是0x7000
; - 因此,与线性地址
0x7e08
对应的物理页物理地址是0x7000
;
三、info tab : 查看当前任务的页表信息
1、初次进入分页模式
2、info tab 查看当前任务的页表信息:初次进入分页模式后的页表信息
<bochs:11> info tab
cr3: 0x000000020000
0x00000000-0x000fffff -> 0x000000000000-0x0000000fffff
0xffc00000-0xffc00fff -> 0x000000021000-0x000000021fff
0xfffff000-0xffffffff -> 0x000000020000-0x000000020fff
-
复习:如何访问页目录表自己的表项以及访问页表自己的表项(即,为什么页目录表的起始线性地址是
0x FFFF F000
、页表的起始线性地址是0xFFC0 0000
)
- 第一行:
0x00000000-0x000fffff -> 0x000000000000-0x0000000fffff
虚拟内存空间的低端1MB,即,线性地址 0x00000000-0x000fffff
对应着物理地址 0x00000000-0x000fffff
一模一样
这是正确的,因为在初次进入分页模式时,
就是要建立低端1MB内存空间与物理地址的的一一对应,
就是要使这部分线性地址与物理地址相同。
- 第二行:
0xffc00000-0xffc00fff -> 0x000000021000-0x000000021fff
见复习部分
可以知道 线性地址 0xffc00000 是页表自己的起始线性地址;
为了用线性地址来访问和修改页表自己的内容,
我们把页表当成普通的页,把页目录表当成页表用。
在这种情况下,页表的线性首地址是 0xffc00000 ;
因此 0xffc00000-0xffc00fff 这段4KB的线性地址区间
对应的是页表实际物理地址 0x000000021000-0x000000021fff
(可见上方内存示意图)
- 第三行:
0xfffff000-0xffffffff -> 0x000000020000-0x000000020fff
见复习部分
可以知道 线性地址 0xfffff000 是页目录表自己的起始线性地址;
为了用线性地址来访问和修改页目录表自己的内容,
页目录表的最后一个目录项,登记的是页目录表自己的物理地址;
因此,页目录表自己的起始线性地址是 0xfffff000;
即,0xfffff000-0xffffffff 的4KB的线性地址区间对应的
实际物理地址区间是 0x000000020000-0x000000020fff
(可以见上方内存示意图)
3、进入用户程序 ,就可以查看用户程序的页表信息
-
b 0x0038:0x0613
跳转到内核程序的任务切换指令; -
s
通过单步调试进入用户程序;
<bochs:13> b 0x0038:0x0613
<bochs:14> c
(0) Breakpoint 4, 0x000000008004106b in ?? ()
Next at t=17806152
(0) [0x00000004106b] 0038:0000000000000613 (unk. ctxt)
<bochs:15> s
Next at t=17806153
(0) [0x00000013585b] 0007:000000000001f85b (unk. ctxt)
<bochs:16> info tab
cr3: 0x000000141000
0x00000000-0x00000fff -> 0x00000002f000-0x00000002ffff
0x00001000-0x00001fff -> 0x000000031000-0x000000031fff
0x00002000-0x00002fff -> 0x000000033000-0x000000033fff
0x00003000-0x00003fff -> 0x000000035000-0x000000035fff
0x00004000-0x00004fff -> 0x000000037000-0x000000037fff
0x00005000-0x00005fff -> 0x000000101000-0x000000101fff
0x00006000-0x00006fff -> 0x000000103000-0x000000103fff
0x00007000-0x00007fff -> 0x000000105000-0x000000105fff
0x00008000-0x00008fff -> 0x000000107000-0x000000107fff
0x00009000-0x00009fff -> 0x000000109000-0x000000109fff
0x0000a000-0x0000afff -> 0x00000010b000-0x00000010bfff
0x0000b000-0x0000bfff -> 0x00000010d000-0x00000010dfff
0x0000c000-0x0000cfff -> 0x00000010f000-0x00000010ffff
0x0000d000-0x0000dfff -> 0x000000111000-0x000000111fff
0x0000e000-0x0000efff -> 0x000000113000-0x000000113fff
0x0000f000-0x0000ffff -> 0x000000115000-0x000000115fff
0x00010000-0x00010fff -> 0x000000117000-0x000000117fff
0x00011000-0x00011fff -> 0x000000119000-0x000000119fff
0x00012000-0x00012fff -> 0x00000011b000-0x00000011bfff
0x00013000-0x00013fff -> 0x00000011d000-0x00000011dfff
0x00014000-0x00014fff -> 0x00000011f000-0x00000011ffff
0x00015000-0x00015fff -> 0x000000121000-0x000000121fff
0x00016000-0x00016fff -> 0x000000123000-0x000000123fff
0x00017000-0x00017fff -> 0x000000125000-0x000000125fff
0x00018000-0x00018fff -> 0x000000127000-0x000000127fff
0x00019000-0x00019fff -> 0x000000129000-0x000000129fff
0x0001a000-0x0001afff -> 0x00000012b000-0x00000012bfff
0x0001b000-0x0001bfff -> 0x00000012d000-0x00000012dfff
0x0001c000-0x0001cfff -> 0x00000012f000-0x00000012ffff
0x0001d000-0x0001dfff -> 0x000000131000-0x000000131fff
0x0001e000-0x0001efff -> 0x000000133000-0x000000133fff
0x0001f000-0x0001ffff -> 0x000000135000-0x000000135fff
0x00020000-0x00020fff -> 0x000000139000-0x000000139fff
0x00021000-0x00021fff -> 0x00000013b000-0x00000013bfff
0x00022000-0x00022fff -> 0x00000013d000-0x00000013dfff
0x00023000-0x00024fff -> 0x00000013f000-0x000000140fff
0x80000000-0x800fffff -> 0x000000000000-0x0000000fffff
0x80100000-0x80100fff -> 0x000000029000-0x000000029fff
0x80101000-0x80101fff -> 0x00000002b000-0x00000002bfff
0x80102000-0x80102fff -> 0x000000137000-0x000000137fff
0xff800000-0xff800fff -> 0x00000002d000-0x00000002dfff
0xffa00000-0xffa00fff -> 0x000000021000-0x000000021fff
0xffbfe000-0xffbfefff -> 0x000000141000-0x000000141fff
0xffbff000-0xffbfffff -> 0x000000020000-0x000000020fff
0xffc00000-0xffc00fff -> 0x00000002d000-0x00000002dfff
0xffe00000-0xffe00fff -> 0x000000021000-0x000000021fff
0xffffe000-0xffffefff -> 0x000000141000-0x000000141fff
0xfffff000-0xffffffff -> 0x000000020000-0x000000020fff
<bochs:17>
四、x :使用线性地址查看内存信息
- 进入用户程序后,使用bochs指令
x + 线性地址
可以查看内存信息; -
x 0x00
查看用户程序的第一个双字,即用户程序长度; -
x 0x04
查看用户程序的第二个双字,即标号start
的线性地址,用户程序的入口线性地址; - 复习,使用
xp + 物理地址
查看内存内容,可见这里的p代表的就是physical 物理的意思