|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
反汇编Bios中断例程的方法求教
思路:
1 电脑启动后,会进入实模式,从0000:0000处创建中断向量表;
2 BIOS中断程序被加载到了内存中;
3 CPU跳至0000:7c00处执行引导程序。
因此,我用汇编写好引导程序,加入写软盘功能,将0000:0000~FFFF:FFFF的内存全部写入到软盘,然后利用反汇编工具对其反汇编以得到BIOS中断程序的汇编代码。
行动步骤:
1 用虚拟机(VirtualBox)创建一台电脑;
2 虚拟两个软驱;
3 在linux下利用nasm编译引导程序(boot),生成.bin文件,然后使用linux的dd命令(如dd if=boot.bin of=boot.img)将其虚拟成软盘镜像。
4 继续使用dd命令创建一个空白软盘镜像(dd if=/dev/zero of=blank.img bs=1474560 count=1)。bs的作用是限制大小,1474560=1.44m软盘(不知道对不对)
5 分别将两个镜像装进软驱,从0号软盘启动虚拟电脑。出现问候后按回车执行写软盘程序。
6 将0000:0000~FFFF:FFFF的内存全部写入到1号软盘。
进行到这里,问题来了:
1 内存中的数据有一部分成功写入到了空白软盘,内存F000:0000以后应该有数据的,可是软盘里没有,连0000:FC00的数据都没有写入软盘,应该是我的 写软盘代码 有问题。
2 上述思路和步骤是否存在问题,大神们能否指点一下。
3 读软盘的程序也有问题,本想把软盘内容读到0000:7e00处,可直接将es=0000h,bx=7e00h的话程序会卡死,将es=07e0h,bp=0的话可以读,但是读到的内存位置变成了07e0:000a
3 代码附后,因为是刚刚从MASM转入学习NASM,代码可能不太好读,请大神包涵。
- org 07c00h
- mov ax,cs ;显示问候
- mov es,ax
- mov ax,BootMessage
- mov bp,ax
- mov cx,6
- mov dx,0
- call showgreen
- mov ch,00000000b ;设置光标形状
- mov cl,00010000b
- mov ah,01h ;中断入口
- int 10h
-
-
- call newline ;换行
-
- r16h:
- mov ah,0 ;等待键盘输入
- int 16h
- mov ah,0eh ;将输入输出至屏幕
- mov bx,00001010b
- mov cx,1
- int 10h
-
- cmp al,0dh ;回车键结束输入
- je COPY
- jne r16h
- COPY: ;写软盘程序,第一段写一个柱面
- push es
- mov si,0 ;计数器
- mov ax,0h
- mov es,ax ;内存基地址
- mov bx,0h ;内存偏移地址
- mov ah,03h ;int13h 写扇区入口
- mov al,18 ;写扇区的数量
- mov ch,0 ;柱面 或者说 磁道
- mov cl,1 ;第一个扇区开始
- mov dh,0 ;驱动号 或者说 盘面号
- mov dl,1 ;驱动器号 0~7f h 软盘
- int 13h
-
- go: push ax ;储存参数,以便开始写第二个柱面
- mov ax,es
- add ax,240h ;下一个内存基地址
- mov es,ax
- mov bx,0
- pop ax
- inc ch ;下一个柱面或者说磁道
- inc si ;计数器加1
- cmp si,80 ;如果写够了80个磁道,就需要换盘面了
- je C_1
- int 13h
- jmp go
- C_1: ;写软盘第二盘面
- mov si,0 ;计数器重新清零
- push ax
- mov ax,es
- add ax,240h
- mov es,ax ;内存基地址
- mov bx,0 ;内存偏移地址
- pop ax
- mov ch,0 ;柱面 或者说 磁道
- mov cl,1 ;第一个扇区开始
- mov dh,1 ;驱动号 或者说 盘面号
- mov dl,1 ;驱动器号 0~7f h 软盘
- int 13h
-
- go1:
- push ax ;储存参数
- mov ax,es
- add ax,240h ;下一个内存基地址
- mov es,ax
- mov bx,0
- pop ax
- inc ch ;下一个磁道
- inc si ;计数器加1
- cmp si,33 ;如果写够了113个磁道,就写了FE400个数据了
- ;如果直接写114个磁道,es=FE40 + 240 =10080将产生溢出
- je C_end
- int 13h
- jmp go1
-
- C_end:
- mov bx,2400h ;继续多写入一个磁道,写够100800 h个数据
- inc ch
- int 13h
-
- mov al,'o' ;显示一个o,表示程序可以执行到这一步
- mov ah,0eh
- mov bx,00001010b
- mov cx,1
- int 10h
- pop es
- jmp r16h ;跳回等待输入
- showgreen: ;以绿色显示指定位置的字符串,需要设置es,bp,cx,dx
- mov ax,01301h
- mov bx,00001010b
- int 10h
- ret
- loadf: ;读软盘子程序
- ;读取软盘1至7e00 可软盘内容是复制到了7e0a 前9个位置留空了,为什么?
- push es
- mov ax,07e0h
- mov es,ax
- mov bp,0h
- mov ah,2 ;int13 入口参数
- mov al,2 ;读取两个扇区
- mov cx,0001h ;从第一扇区开始
- mov dx,0001h ;1号驱动器(0~80为软驱
- int 13h
- pop es
- ret
-
-
- newline:
- mov ah,03h ;获取光标位置
- int 10h
- inc dh ;设置光标位置,换行
- mov dl,0 ;行首
- mov ah,02h ;
- int 10h
- ret
-
- BootMessage: db "Hello!" ; 6byte
- Smessage: db "Well come to Buu" ; 16byte
- Load: db "Load successfully..."
- db 0ah
- db "Do you want to continue? " ; System-Load byte
- db "Press ENTER"
- System: dw 0h,07e1h ; 系统入口地址
- times 510-($-$) db 0
- dw 0xaa55
复制代码
这个问题有意思,我感兴趣,我找个时间给你试一下
^_^
|
|