1.初始化堆栈
app_lba_start equ 100
SECTION mbr align=16 vstart=0x7c00
mov ax, 0
mov ss, ax
mov sp, ax
times 510-($-$$) db 0
db 0x55, 0xaa
设置下堆栈段与堆栈指针。
2. 初始化显示代码。
app_lba_start equ 100
phy_base equ 0x10000
SECTION mbr align=16 vstart=0x7c00
mov ax, 0
mov ss, ax
mov sp, ax
mov ax, 0x1000;
mov ds, ax
call read_hard_disk_0
call DIS
jmp $
read_hard_disk_0: ;从硬盘读取一个逻辑扇区
;输入:DI:SI=起始逻辑扇区号 ; DS:BX=目标缓冲区地址
push ax
push bx
push cx
push dx
mov dx,0x1f2
mov al,1
out dx,al ;读取的扇区数
inc dx ;0x1f3
mov al,0x64
out dx,al ;LBA地址7~0
inc dx ;0x1f4
mov al,0x00 ;测试读取0扇区内容
out dx,al ;LBA地址15~8
inc dx ;0x1f5
mov al,0x00
out dx,al ;LBA地址23~16
inc dx ;0x1f6
mov al,0xe0 ;LBA28模式,主盘,LBA地址27~24
out dx,al
inc dx ;0x1f7
mov al,0x20 ;读命令
out dx,al
.waits:
in al,dx
and al,0x88
cmp al,0x08
jnz .waits ;不忙,且硬盘已准备好数据传输
mov cx,256 ;总共要读取的字数
mov dx,0x1f0
.readw:
in ax,dx
mov [bx],ax
add bx,2
loop .readw
pop dx
pop cx
pop bx
pop ax
ret
DIS:
push ax
push bx
push cx
push dx
mov ax, 0xb800 ;显示屏幕对应的寄存器
mov es, ax
mov bx, 2
mov cx, 0xffff
.LOOP_CLR:
mov byte [es:0x00], 'f'
mov byte [es:0x01], 0x07
mov byte [es:bx], 0x00
add bx, 2
LOOP .LOOP_CLR
pop dx
pop cx
pop bx
pop ax
ret
times 510-($-$$) db 0
db 0x55, 0xaa
以上代码便是将硬盘中的代码拷贝到内存中去。
3.
1)接下来比较重要,是加载引导用户程序。
再次看下用户代码的结构。这个比较重要。
;===============================================================================
SECTION header vstart=0 ;定义用户程序头部段
program_length dd program_end ;程序总长度[0x00]
;用户程序入口点
code_entry dw start ;偏移地址[0x04]
dd section.code_1.start ;段地址[0x06]
realloc_tbl_len dw (header_end-code_1_segment)/3
;段重定位表项个数[0x0a]
;段重定位表
code_1_segment dd section.code_1.start ;[0x0c]
code_2_segment dd section.code_2.start ;[0x10]
data_1_segment dd section.data_1.start ;[0x14]
stack_segment dd section.stack.start ;[0x1c]
header_end:
;===============================================================================
SECTION code_1 align=16 vstart=0 ;定义代码段1(16字节对齐)
start:
mov ax, 0
;===============================================================================
SECTION code_2 align=16 vstart=0 ;定义代码段2(16字节对齐)
;转移到代码段1接着执行
;===============================================================================
SECTION data_1 align=16 vstart=0
fuxuan db ' This is fuxuan '
;===============================================================================
SECTION stack align=16 vstart=0
;resb 256
stack_end:
;===============================================================================
SECTION trail align=16
program_end:
对比观察编译后的代码结构与应用程序的结构.了解应用程序的头部存放的是是什么?
2) 分析如何加载这些头部数据.