学习笔记
《x86汇编语言:从实模式到保护模式》
https://www.jianshu.com/p/d481cb547e9f
代码运行
运行截图 第16章 本章程序运行截图.PNG代码使用
-
nasmide.exe 编译源码文件 :加载程序
c13_mbr.asm
,内核程序c16_core.asm
,用户程序c16.asm
; -
fixvhdwr.exe 写扇区二进制
.bin
文件:c13_mbr.bin(逻辑扇区号LBA:0)
、c16_core.bin(LBA:1)
、c16.bin(LBA:50)
; - 运行
VM virtual box
.
平坦模式下的用户任务
代码功能
- 显示当前任务4GB虚拟地址空间内的前88个双字,每次先显示两个空格,然后再显示双字的值,这样形成的效果是每行8个双字,共11行。
完整源码 — 源码文件 c16.asm
;代码清单16-2
;文件名:c16.asm
;文件说明:用户程序
;创建日期:2012-05-25 13:53
program_length dd program_end ;程序总长度#0x00
entry_point dd start ;程序入口点#0x04
salt_position dd salt_begin ;SALT表起始偏移量#0x08
salt_items dd (salt_end-salt_begin)/256 ;SALT条目数#0x0C
;-------------------------------------------------------------------------------
;符号地址检索表
salt_begin:
PrintString db '@PrintString'
times 256-($-PrintString) db 0
TerminateProgram db '@TerminateProgram'
times 256-($-TerminateProgram) db 0
;-------------------------------------------------------------------------------
reserved times 256*500 db 0 ;保留一个空白区,以演示分页
;-------------------------------------------------------------------------------
ReadDiskData db '@ReadDiskData'
times 256-($-ReadDiskData) db 0
PrintDwordAsHex db '@PrintDwordAsHexString'
times 256-($-PrintDwordAsHex) db 0
salt_end:
message_0 db 0x0d,0x0a,
db ' ............User task is running with '
db 'paging enabled!............',0x0d,0x0a,0
space db 0x20,0x20,0
;-------------------------------------------------------------------------------
[bits 32]
;-------------------------------------------------------------------------------
start:
mov ebx,message_0
call far [PrintString]
xor esi,esi
mov ecx,88
.b1:
mov ebx,space
call far [PrintString]
mov edx,[esi*4]
call far [PrintDwordAsHex]
inc esi
loop .b1
call far [TerminateProgram] ;退出,并将控制权返回到核心
;-------------------------------------------------------------------------------
program_end:
平坦模式
1、用户程序在平坦模式之下,所有的段共享4GB虚拟内存空间
- 下面的代码来自内核程序,源码文件
c16_core.asm
过程 [make_seg_descriptor] 位于内核程序
输入参数
EAX=线性基地址
EBX=段界限
ECX=属性
返回 EDX:EAX=描述符
;建立程序代码段描述符
mov eax,0x00000000
mov ebx,0x000fffff
mov ecx,0x00c0f800
call sys_routine_seg_sel:make_seg_descriptor
mov ebx,esi
call fill_descriptor_in_ldt
or cx,0000_0000_0000_0011B
;建立程序数据段描述符
mov eax,0x00000000
mov ebx,0x000fffff
mov ecx,0x00c0f200
call sys_routine_seg_sel:make_seg_descriptor
mov ebx,esi
call fill_descriptor_in_ldt
or cx,0000_0000_0000_0011B
- 可以看见,代码段和数据段的线性基地址都是
0x00000000
,两个段的大小都是4GB,不光这两个段,栈段也要与这些段一起共享这4GB的虚拟内存空间;
2、何为平坦模式?
- 在平坦模式下,名义上不分段,但实际上是只分一个大段,在这种情况下,不管程序实际加载到哪里,代码段、数据段和栈段,其描述符的基地址都固定为
0x00000000
- 将段的大小定义成4GB,是希望可以发出任何虚拟地址,而不会被段部件的检查机制阻挠。
网友评论