注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

编程学习

我的网上家园

 
 
 

日志

 
 

简单的加载器练习  

2013-01-22 15:38:38|  分类: 80x86汇编学习 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |
; x86汇编语言:从实模式到保护模式 第8章练习
; 加载器编写练习
; 加载位于硬盘LBA 100扇区的用户程序到内存,然后把控制权移交给用户程序

; 用户程序结构: 0x0: 程序长度(4字节) 0x4:程序入口点的偏移地址(两字节) 0x6:程序入口点的段地址(4字节) 
; 用户程序结构: 0xa: 段重定位表项数(2字节) 0xc: 段重定位表(每个表项4字节)


app_lba_start equ 100 ;常量定义,用户程序在硬盘LBA 100扇区

section mbr vstart=0x7c00 ;段定义,汇编地址从0X7C00开始计算.

xor ax,ax
mov ss,ax
mov sp,ax ;堆栈初始化 0:0

mov ax,[cs:phy_base]
mov dx,[cs:phy_base+0x2]
mov bx,16
div bx
mov ds,ax
mov es,ax ;DS=ES=0X1000,要加载到的目标内存段地址
mov si,app_lba_start
mov di,0 ;DI:SI为要读取的硬盘LBA地址
mov bx,0 ;DS:BX为要加载到的目标内存地址.
call read_harddisk_0 ;调用读硬盘扇区子程序

mov ax,[0]
mov dx,[2] ;DX:AX为用户程序长度
mov bx,512
div bx
or dx,dx
jnz s1
dec ax ;程序长度为整数个扇区数时,扇区数减1,因为已经读取了一个扇区
s1:
or ax,ax
jz read_end
mov cx,ax
push ds
mov bx,0
load:
mov ax,ds
add ax,0x20
mov ds,ax
add si,1
adc di,0
call read_harddisk_0
loop load ;循环装入程序到内存
pop ds
read_end:

mov ax,[0x6]
mov dx,[0x8]
call calc_segment ;调用段地址计算子程序
mov [0x6],ax
mov cx,[0xa] ;段重定位表项数
mov bx,0xc
prog_seg:
mov ax,[bx]
mov dx,[bx+2]
call calc_segment
mov [bx],ax
add bx,4
loop prog_seg ;重新计算段地址
jmp far [0x4] ;移交控制权


;子程序 
;入口参数 di:si为要读取的起始LBA地址,DS:BX为要加载到的内存地址
read_harddisk_0:
push bx
push ax
push dx
push cx
mov dx,0x1f2
mov al,1
out dx,al ;读取扇区数
inc dx ;0x1f3
mov ax,si
out dx,al
inc dx ;0x1f4
mov al,ah
out dx,al
inc dx ;0x1f5
mov ax,di
out dx,al
inc dx ;0x1f6
or ah,1110_0000B
mov al,ah
out dx,al
inc dx
mov al,0x20 ;读操作
out dx,al
waits:
in al,dx
and al,0x88
cmp al,0x8
jnz waits
mov dx,0x1f0 ;数据端口
mov cx,256
read_s:
in ax,dx
mov [bx],ax
add bx,2
loop read_s
pop cx
pop dx
pop ax
pop bx
ret

;子程序
;入口参数: DX:AX为32位的汇编段地址,AX为返回的重定位后的段地址.
calc_segment:
push dx
add ax,[cs:phy_base]
adc dx,[cs:phy_base+0x2]
shr ax,4
shl dl,4
or ah,dl
pop dx
ret

phy_base dd 0x10000 ;定义要加载的目标内存地址
times 510-($-$$) db 0
db 0x55,0xaa
  评论这张
 
阅读(43)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2017