王爽.汇编.第三版.课程设计2

xiaoxiao2021-02-27  132

读完王爽汇编第三版的精简版的操作系统,对没有错,就是操作系统 需要注意的是: 0、多谢:http://www.cnblogs.com/S-E-P/archive/2010/04/06/2045067.html的代码。 1、将代码拷贝到软盘,然后再从软盘拷贝到内存的时候,程序中用到的字符串怎么寻址,因为按照目前书中的知识面,如果用标号访问字符串,则用的是偏移地址,而代码经过这样的2次拷贝后,地址早不知道偏移到哪去了(字符串地址=cs+偏移,如果要固定死cs,就限制太大了)。 解决方案:就是将各个功能分段,将每个功能放到独立的段里,此问题就大大简化了。 2、需要注意的是,功能函数的返回可以用retf简化程序的跳转,如下,跳转到2000:0

mov ax,2000h push ax mov ax,0 push ax retf

当然也可以用call dword 2000:0。 测试环境: 1、我用的是vbox安装MS dos7.10。 2、用winImage制作共享软盘share.vfd和系统启动盘boot.vfd。注意,同时只能有一个程序访问vfd文件,因此winImage修改vfd时,要关闭dos,反之亦然。 2.1 share.vfd用于windows和vbox的dos系统共享软件用的,放在2号软驱(盘符B:) 2.2 boot.vfd是用于写入自制的操作系统的,放在1号软驱(盘符A:),这和bios的启动规则有关系,不赘述(见Page312) 测试过程: 直接在dos上编译代码的直接忽略这些步骤,我是在windows上的dosbox上测试并编辑代码,然后再virtual dos上测试。 1、将代码保存成kcsj2.asm,上位机编译成程序kcsj2.exe。 2、用winImage打开share.vfd,拖入kcsj.exe保存。 3、直接在v dos上将kcsj2.exe拷贝到c盘,执行kcsj2.exe制作系统盘,重启。 附录一,代码:

; 简化kcsj2的程序 ; 任务菜单,只保留,restpc,startsystem,clock(只显示时间) ;注意有软盘模拟工具 ;系统盘制作 段 assume cs:FloppyInstallCode FloppyInstallCode segment start: ;------------------- ;注意,此处没有考虑拷贝的长度,软盘上肯定有多余的字 ;节,但是没有关系,因为指令会将那些字节跳过去 ;------------------- ; 拷贝代码引导程序 mov ax, lodesysSeg mov es, ax mov bx, 0 mov al,1 mov ch,0 mov cl,1 ; 第一扇区 mov dl,0 mov dh,0 mov ah,3 int 13h call showerror ; 拷贝任务程序 mov ax, taskCodeSeg mov es, ax mov bx, 0 mov al,15 ; 此处是为了保险,写的15 mov cl,2 ; 第二扇区 mov ah,3 int 13h call showerror ;安装结束,返回 mov ax,4c00h int 21h showerror: jmp short showerror_code err db 'error: ', 0 ok db 'ok',0 buff db '0123456789abcdef' showerror_code: push ax push bx push ds mov bx, 0b800h mov ds, bx cmp ah, 0 jne showerror_error mov byte ptr ds:[18], 'o' mov byte ptr ds:[20], 'k' jmp short showerror_exit showerror_error: mov byte ptr ds:[0], 'e' mov byte ptr ds:[2], 'r' mov byte ptr ds:[4], 'r' mov byte ptr ds:[6], 'o' mov byte ptr ds:[8], 'r' mov byte ptr ds:[10], ':' mov al, ah and al, 00001111b shr ah, 1 shr ah, 1 shr ah, 1 shr ah, 1 sub bx, bx mov bl, al mov bl, buff[bx] mov byte ptr ds:[12], bl mov bl, ah mov bl, buff[bx] mov byte ptr ds:[14], bl mov byte ptr ds:[16], '!' jmp short showerror_exit showerror_exit: pop ds pop bx pop ax ret FloppyInstallCode ends ;-------------------------------- ;引导扇区的程序 ;主引导程序 ;包含所有子程序的直接定址表,扇区加载程序,菜单 assume cs:lodesysSeg lodesysSeg segment init: call loadsys ; 调到第二扇区执行,2000地址,自己任意设定,只要大于512字节跳过lodesysSeg就可以了 mov ax,2000h push ax mov ax,0 push ax retf loadsys: mov ax,2000h ;软盘数据读取到2000:0 mov es,ax mov bx,0 mov al,15 ;读取的扇区数 mov ch,0 ;0磁道 mov cl,2 ;2扇区 mov dl,0 ;0号驱动器 mov dh,0 ;0面 mov ah,2 int 13h ret lodesysSegend: nop lodesysSeg ends ;------------------------------------------ ; 任务代码, 第二扇区以后 assume cs:taskCodeSeg taskCodeSeg segment realcode: jmp short run tip1 db "1. rest pc",0 tip2 db "2. start system",0 tip3 db "3. clock",0 tipoff dw tip1, tip2, tip3 run: ; mov dh, 12 ; mov dl, 34 ; call showtime call showtips mov ah, 0 int 16h ; al cmp al, '1' je if_1 cmp al, '2' je if_2 cmp al, '3' je if_3 cmp al, 'q' jmp exit jmp run if_1: call reset_pc jmp run if_2: call start_system jmp run if_3: call clock jmp run mov ax, 4c00h int 21h showtips: push ds push es push si push di push ax push bx push cx push dx mov ax, 0b800h mov ds, ax mov ax, 0 mov dx, 0 ; ?st tip mov si, 0 ; screen pos mov cx, 3 ; 3 tips showtips_loop: push si mov bx, dx mov bx, tipoff[bx] showonetip: mov al, byte ptr cs:[bx] cmp al, 0 je showonetip_over mov byte ptr ds:[si], al mov byte ptr ds:[si+1], 00000100b add si, 2 inc bx jmp showonetip showonetip_over: pop si add si, 160 add dx, 2 loop showtips_loop pop dx pop cx pop bx pop ax pop di pop si pop es pop ds ret ;--------------- exit: mov ax, 4c00h int 21h reset_pc: ;直接设置cs:ip,跳转到ffff:0 mov ax, 0 mov word ptr ds:[0], ax mov ax, 0ffffh mov ds:[2], ax call dword ptr ds:[0] ret start_system: ;将C盘的第001扇区读入到0:7C00 mov ax, 0 mov es, ax mov bx, 07c00h mov al, 1 mov ch, 0 mov cl, 1 mov dl, 80h mov dh, 0 mov ah, 2 int 13h ; 返回到0:7c00,注意retf的使用 mov ax, 0h push ax mov ax, 7c00h push ax retf clock: ;显示时间 mov dh, 12 mov dl, 34 call showtime ret ;-------------------------- ; show cmos time ; 参数:dh:dl,位置中的行和列 showtime: jmp short showtime_code showtime_data: db 9,8,7,4,2,0 ; 端口中时间的字节偏移 db '// :: ' ; 间隔符 showtime_code: push es push si push ds push di push bx push cx push dx call clearscreen ; 写入的位置 mov ax, 0b800h mov es, ax push dx sub ax, ax mov al, dh mov bx, 160 mul bx mov cx, ax pop dx sub ax, ax mov al, dl mov bx, 2 mul bx add ax, cx mov di, ax ; ds:si=cmos偏移字段缓存区的地址 mov ax, cs mov ds, ax mov ax, offset showtime_data mov si, ax mov cx, 6 showtime_looptime: push cx ;偏移 mov al, byte ptr ds:[si] out 70h, al in al, 71h ;十位的计算 mov bh, al and bh, 11110000b mov cl, 4 shr bh, cl add bh, 30h mov byte ptr es:[di], bh mov byte ptr es:[di+1], 00000010b ;个位的计算 mov bl, al and bl, 00001111b add bl, 30h mov byte ptr es:[di+2], bl mov byte ptr es:[di+3], 00000010b ;显示分隔符 mov al, byte ptr ds:[si+6] mov byte ptr es:[di+4], al mov byte ptr es:[di+5], 00000010b add di, 6 inc si pop cx loop showtime_looptime pop dx pop cx pop bx pop di pop ds pop si pop es ret ;------------------------------------------ ; 参数:无 ; 清屏 clearscreen: push ax push bx push cx push es mov ax, 0b800h mov es, ax mov bx, 0 mov ax, 0 mov cx, 160*25 clearscreen_loop: mov byte ptr word ptr es:[bx], ' ' add bx,2 loop clearscreen_loop pop es pop cx pop bx pop ax ret taskCodeSeg ends end start

附录二,vfd注意事项: 1、新建 2、不要直接保存,要使用save as: 3、剩下的dos和winImage不要同时使用就可以了

转载请注明原文地址: https://www.6miu.com/read-13795.html

最新回复(0)