鱼C论坛

 找回密码
 立即注册
查看: 4507|回复: 4

[技术交流] 关于王爽老师汇编语言程序设计课程设计2的程序

[复制链接]
发表于 2013-11-4 22:51:05 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 guotong 于 2013-11-12 22:04 编辑

;===============================================================
;"="表示子程序或功能程序分割段
;"~"表示子程序或功能程序内部分割段
;以上两种符号只起到程序之间界限划分
;";"是起到程序注释作用
;===============================================================
assume cs:code
code segment
;===============================================================
;  程序功能为将从floppy开始的内容从软驱
;  0面0磁道1扇区开始写入
;al设置要使用的扇区数
;ch设置软盘从0磁道开始
;cl设置软盘从1号扇区开始
;dh设置软盘从0磁头即软盘0面开始
;dl设置从软驱开始的驱动号
;===============================================================
start:
mov ax,floppy_end-floppy ;算出要加载程序的大小,商为扇区数,余数为扇区数+1
mov dx,0  ;dx存储余数
mov bx,512  ;512为1个扇区的总字节数
div bx
inc al   ;扇区数+余数=总扇区数
push cs   ;程序入口地址复值给es(因为int 13h要写入和读取的段地址和偏移地址总是和es:bx指向相关联)
pop es
mov bx,offset floppy ;将偏移地址设置为floppy
mov ch,0
mov cl,1
mov dh,0
mov dl,0
mov ah,3  ;设置中断历程的程序功能号为3(写入功能)
int 13h   ;调用int 13h中断历程

mov ax,4c00h
int 21h
;===============================================================
;加载到软盘0面0道1扇区开始的内容
;===============================================================
floppy:
jmp read
;===============================================================
;直接定址表
;===============================================================
;*******************************************************
;此为主程序功能号定址表
table dw function1-floppy,function2-floppy
       dw function3-floppy,function4-floppy ;得到相应的功能程序入口地址
;*******************************************************
;此为主界面显示内容
menu db "*******Main  Menu*******",0 ;主菜单显示用定址表 show_menu,每行25个字节
      db "1)reset PC              ",0
      db "2)start system          ",0
      db "3)clock                 ",0
      db "4)set clock             ",0
      db "input choose number:[ ] ",0
;*******************************************************
;此为COMS时间格式
hint db "Press F1 key chang color,Press ESC key retun MainMenu",0
hint1 db "Press Enter key or ESC key retun MainMenu",0
time db "YY/MM/DD hh:mm:ss",0
  ;0123456789abcdefg
time1 db "YY/MM/DD hh:mm:ss",0
cmos db 9,8,7,4,2,0
char db "  /  /     :  :  ",0
  ;0123456789abcdefg
;===============================================================
;read子程序,功能是将floppy到floppy_end中的功能写入到内从中
;由于功能中要引导硬盘中的80h驱动0面0道1扇区中的内容到0:7c00h中
;所以软驱写入到内存中的内容就应该用7c00h+200h(200h=512B)
;即写入0:7e00h
;从0:7c00h处引导
;===============================================================
read:
mov ax,floppy_end-floppy
mov dx,0
mov bx,512
div bx
inc al  ;得出所需扇区数
mov bx,0
mov es,bx
mov bx,7e00h ;0:7e00开始接收软盘内容
mov ch,0
mov cl,2 ;将软盘2号扇区内容写到0:7e00处
mov dh,0
mov dl,0
mov ah,2 ;读命令
int 13h
mov ax,7c0h ;00000h+7c00h=07c00h换算成段地址为07c0h
push ax
mov ax,show_menu-floppy
push ax
retf  ;CS:IP指向 0:7c00+show_menu-floppy
;===============================================================
;show_menu主程序入口地址
;===============================================================
show_menu:
call clean
push cs
pop ds
mov dh,10 ;显示用行号
mov dl,25 ;显示用列号
mov si,menu-floppy ;得到menu的偏移地址
mov cx,6  ;menu中共有6行
show_menu0:
  push cx
  mov cl,2 ;cl设置显示颜色
  call show_str ;调用显示输出的子程序
  add si,25
  inc dh
  pop cx
  loop show_menu0
mov ah,2
mov bh,0
mov dh,15
mov dl,46
int 10h
;===============================================================
;choose子程序,主程序下监听用户输入的字符得到相应的功能号
;===============================================================
choose:
mov ax,0
int 16h
cmp al,'1'
jb show_menu
cmp al,'4'
ja show_menu

mov bx,0b800h
mov es,bx
mov bx,160*15+46*2
mov es:[bx],al

mov si,table-floppy
sub al,31h
mov bl,al
mov bh,0
add bx,bx
add bx,si  ;计算bx在table中的偏移地址
mov ax,0
int 16h
cmp ah,1ch
jne show_menu
call word ptr cs:[bx]   ;调用相应的功能程序
jmp show_menu  ;返回后回到主程序界面
;===============================================================
;function1,功能程序1,重新启动计算机
;===============================================================
function1:
mov ax,0ffffh
push ax
mov ax,0
push ax
retf
;===============================================================
;function3,功能程序3,显示CMOS时间
;===============================================================
function3:
push ax
push bx
push cx
push dx
push si
push ds
push es
call clean ;清屏
mov ah,2
mov bh,0
mov dh,0
mov dl,0
int 10h
mov dh,0
mov dl,0
mov cl,2
mov si,hint-floppy
call show_str  ;将hint字符串显示在首行
mov dh,10
mov dl,30
mov cl,2
mov si,time1-floppy
call show_str
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;将时间放入到time表中,time在直接定址表中
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
mov cx,2
clock:
  mov bx,cmos-floppy
  mov si,time-floppy
  push cx
  mov cx,6
  clock0:
   push cx
   mov al,[bx]
   out 70h,al
   in al,71h
   mov ah,al
   mov cl,4
   shr al,cl
   and ah,00001111b
   add ax,3030h
   mov [si],ax
   add si,3
   inc bx
   pop cx
   loop clock0
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
;按下F1改变颜色,按下ESC返回到主菜单,循环显示输出CMOS时间
;~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   
   mov al,0
   in al,60h
   pop cx
   cmp al,3bh
   je color
   cmp al,1
   je clock_ret
   jmp show_time
   color_set:
    mov cx,1
    jmp show_time
   color:
    cmp cx,7
    je color_set
    inc cx
   show_time:
    mov dh,11
    mov dl,30
    mov si,time-floppy
    call show_str
    jmp clock  ;循环显示CMOS时间
clock_ret:
  pop es
  pop ds
  pop si
  pop dx
  pop cx
  pop bx
  pop ax
  ret
;===============================================================
;function4,功能程序,实现对CMOS时间的修改
;===============================================================
function4:
push cx
push dx
push si
push di
call clean
mov dh,0
mov dl,0
mov si,hint1-floppy
mov cl,2
call show_str
mov dh,10
mov dl,30
mov si,time1-floppy
mov cl,2
call show_str

mov dh,11
mov dl,30
mov ah,2
mov si,char-floppy
mov cl,2
call show_str
mov di,0
call get_strs
call write_cmos
call clean_char
mov ah,2
mov bh,0
mov dh,0
mov dl,0
int 10h
pop di
pop si
pop dx
pop cx
ret
;===============================================================
;write_cmos子程序,改写cmos内的内容
;===============================================================
write_cmos:
push ax
push bx
push cx
push si
cmp di,16
jb write_ret  ;如果小于16就不改写cmos中的值
mov bx,cmos-floppy
mov cx,6
write0:
  push cx
  mov al,[bx]
  out 70h,al
  mov ax,[si]
  sub ah,30h
  sub al,30h
  mov cl,4
  shl al,cl
  add al,ah
  out 71h,al
  inc bx
  add si,3
  pop cx
  loop write0
write_ret:
  pop si
  pop cx
  pop bx
  pop ax
  ret
;===============================================================
;clean_char子程序,清楚char栈内的输入,保证下次输入时栈内为空
;===============================================================
clean_char:
push cx
clean_char1:
  mov cx,di
  jcxz clean_char2
  call char_pop
  jmp clean_char1
clean_char2:
  pop cx
  ret
;===============================================================
;get_strs子程序,输入字符并显示字符,将字符入栈或出栈
;===============================================================
get_strs:
push ax
push bx
push dx
call cursor
get_str:
  mov ax,0
  int 16h
  cmp ah,0eh
  je backspace
  cmp ah,1ch
  je enter
  cmp ah,1
  je enter
  cmp al,'0'
  jb get_str
  cmp al,'9'
  ja get_str
  cmp di,16
  ja enter
  call char_push
  call show_str  ;因为在程序功能4中已经定义了dh=9,dl=14,si=char-floppy,所以可以直接调用show_str子程序
  call cursor
  jmp get_str
backspace:
  call char_pop
  call show_str
  call cursor
  jmp get_str
enter:
  pop dx
  pop bx
  pop ax
  ret
;===============================================================
;int_10h ,cursor子程序,置光标
;===============================================================
cursor:
push ax
push bx
push cx
push dx

mov ah,2
mov bh,0
mov cx,di
add dl,cl
int 10h

pop dx
pop cx
pop bx
pop ax
ret
;===============================================================
;char_push子程序,得到的字符入栈
;===============================================================
char_push:
mov bx,di
mov [si][bx],al
inc di
cmp di,2
je add_di
cmp di,5
je add_di
cmp di,8
je add_di
cmp di,11
je add_di
cmp di,14
je add_di ;以上做的目的是为了保留char栈内的/和:
ret
add_di:
  inc di
  ret
;===============================================================
;char_pop子程序,将最后一个入栈的字符出栈
;===============================================================
char_pop:
cmp di,0
je char_ret
cmp di,3
je sub_di
cmp di,6
je sub_di
cmp di,9
je sub_di
cmp di,12
je sub_di
cmp di,15
je sub_di ;以上做的目的是为了保留char栈内的/和:
dec di  ;以上对比都不属于,那么当前di的值为2,di从0开始
mov bx,di
mov al,' '
mov [si][bx],al
ret
sub_di:
  sub di,2
  mov bx,di
  mov al,' '
  mov [si][bx],al
char_ret:
  ret
;===============================================================
;clean子程序,实现清屏功能,是屏幕的字符全部变为空格
;===============================================================
clean:
push bx
push cx
push es
mov bx,0b800h
mov es,bx
mov bx,0
mov cx,2000
clear:
  mov byte ptr es:[bx],' '
  add bx,2
  loop clear
pop es
pop cx
pop bx
ret
;===============================================================
;show_str子程序,显示输出功能,显存地址为b800:0
;===============================================================
show_str:
push ax
push bx
push cx
push dx
push si
push ds
push es
mov ax,0b800h
mov es,ax
mov ax,160
mul dh
mov bx,ax
mov ax,2
mul dl
add bx,ax
mov al,cl
mov cl,0
show_str1:
  mov ch,[si]
  jcxz show_ret
  mov es:[bx],ch  ;偶地址存放字符
  mov es:[bx].1,al ;奇地址存放颜色
  add bx,2
  inc si
  jmp show_str1
show_ret:
  pop es
  pop ds
  pop si
  pop dx
  pop cx
  pop bx
  pop ax
  ret
;===============================================================
;function2,功能程序2,引导现有的操作系统:读取硬盘的0面0磁道1扇区
;      内的引导程序(引导扇区)
;===============================================================
function2:
call clean
mov bx,0
mov es,bx
mov bx,7c00h
mov al,1
mov ch,0
mov cl,1
mov dh,0
mov dl,80h
mov ah,2
int 13h   ;以上是将硬盘引导扇区内容写入内存
mov ax,0  ;以下是将程序执行的入口地址改为0:7c00h共int 19h调用
push ax
mov ax,7c00h
push ax
retf   
;===============================================================
;floppy_end程序结束
;===============================================================
floppy_end:
nop
code ends
end start
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2013-11-16 20:08:57 | 显示全部楼层
光有看的,没有回帖的,给点意见也行啊!真是无语:sad
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2013-11-17 17:20:11 | 显示全部楼层
路过看看哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-9-24 16:54:49 | 显示全部楼层
我先看看!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2021-6-25 22:13:56 | 显示全部楼层
现在距离我汇编学习完成已有一周时间了,这个我没有去做,我只是来看看,因为我学汇编只是为了更好地去学习C语言
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-28 05:30

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表