• 王爽汇编语言课程设计2(不涉及软盘操作,没有功能1,2)


    一开始时思路错了,想着把所有按键的操作都写到 int9中断中,如果这样写会产生一系列错误,与要求也不相符。
    看了看别人的思路后明白了,功能选择应该在主程序中利用 int 16中断来完成,而时钟功能中的esc返回功能和 f 1改变颜色应该借助 int 9中断来完成。

    ;课程设计2
    ;列出功能选项,让用户通过键盘进行选择,界面如下。
    ;(1)reset pc        重新启动计算机
    ;(2)start system    引导现有操作系统
    ;(3)clock           进入时钟程序
    ;(4)set clock       设置时间
    
    assume cs:code,ds:data,ss:stack
    
    data segment
      db '1.reset pc    '
      db '2.start system'
      db '3.clock       '
      db '4.set clock   '
    data ends
    
    stack  segment
      db 256 dup(0)
    stack ends
    
    code  segment
      begin:mov ax,stack
            mov ss,ax
    	mov ax,data
    	mov ds,ax
    
            call anint9            ;安装新的int9中断例程
        gn6:call show              ;显示主菜单
            jmp short en
    	
        gn3:call day                ;功能3显示日期
      gn3_1:call day_color          ;功能3中的改变时钟颜色
            jmp short gn3
    
        gn4:call change_day        ;功能4改变时钟
    
    
    
         en:mov ah,0
            int 16h
    	cmp ah,04h
    	je gn3
    	cmp ah,05h
    	je gn4
    	jmp short en
    
    
            mov ax,4c00h
    	int 21h
    
    
       show:push ax                 ;显示功能函数
            push es
    	push bx
    	push cx
    	push ds
    	push di
            mov ax,0b800h
            mov es,ax
    	mov bx,0
    	mov cx,2000
     shows1:mov byte ptr es:[bx],' '
            add bx,2
    	loop shows1
            mov bx,160*5+2*4
    	mov di,0
    	mov cx,4
    
     shows2:push cx
            mov cx,14
     shows3:mov al,[di]
            mov es:[bx],al
    	inc di
    	add bx,2
    	loop shows3
    	add bx,132
    	pop cx
    	loop shows2
    
            pop di
            pop ds
    	pop cx
    	pop bx
    	pop es
    	pop ax
    	ret
    
            
    
     anint9:push ax                 ;安装新的int9中断例程
            push ds
    	push cx
    	push es
    	push di
    	push si
    
            mov ax,cs
            mov ds,ax
    	mov ax,0
    	mov es,ax
    	mov si,offset int9
    	mov di,204h             ;把新的int9安装到0:0204
    	mov cx,offset int9end-offset int9
    	cld
    	rep movsb
    
    	push es:[9*4]            ;将原int9的入口地址保存到0:0200-0204
    	pop es:[200h]
    	push es:[9*4+2]
    	pop es:[202h]
    
    	cli                      ;设置新的int9的中断向量表
    	mov word ptr es:[9*4],204h
    	mov word ptr es:[9*4+2],0
    	sti
            
    	pop si
    	pop di
    	pop es
    	pop cx
    	pop ds
    	pop ax
    	ret
    
       int9:
            in al,60h
    	
    	
    	pushf                     ;调用原int9中断例程进行处理
    	call dword ptr cs:[200h]
    
            cmp al,01h
    	jne r2
            mov ax,seg gn6
            mov si,offset gn6
    	jmp short retend1
    
         r2:cmp al,3bh
    	jne retend2
    	mov ax,seg gn3_1
    	mov si,offset gn3_1
    	jmp short retend1
    
            jmp short retend2
            
    
    retend1:add sp,4
    	push ax
    	push si
    	mov ah,0
    	int 16h
    	
    retend2:
            iret
    int9end:nop
    
    
    
    
    
        day:pop cx      ;实时动态日期显示
            pop cx
    	mov cx,2
            mov ax,0b800h
    	mov es,ax
    	mov bx,0
    	mov cx,2000
       days:mov byte ptr es:[bx],' '  ;显示日期前先清屏
            add bx,2
    	loop days
    
       day0:mov bx,160*12+40*0        ;显示日期的位置
    	mov dl,9
    	mov cx,6
       day1:mov si,cx
            mov al,dl
    	out 70h,al
    	in al,71h
    	mov ah,al
    	mov cl,4
            shr ah,cl
    	and al,00001111b
    
    	add al,30h
    	add ah,30h
    
    	mov byte ptr es:[bx],ah
    	mov byte ptr es:[bx+2],al
    	mov byte ptr es:[bx+4],':'
    	
    	
            add bx,6       
    	dec dl
    	cmp bx,792h
    	je  day2
    	cmp bx,792h
    	ja  day4
    	jna day3
       day4:inc dl
       day2:sub dl,2
         
       day3:mov cx,si
            loop day1
    
    
    	jmp short day0
    
    
            ret
    
    
    
    day_color:push ax                      ;更改时间颜色
              push es
    	  push bx
    	  mov ax,0b800h
    	  mov es,ax
    	  mov bx,160*12+40*0+1
              mov cx,6
       colors:mov byte ptr es:[bx],2
              mov byte ptr es:[bx+2],2
    	  add bx,6
    	  loop colors
    	  pop bx
    	  pop es
    	  pop ax
    	  ret
    
    
    change_day:push ax                      ;更改CMOS时间
               push es
    	   push bx
    	   push cx
    	   push dx
    
    
               mov ax,0b800h
               mov es,ax
    	   mov bx,160*10+40*0
    	   mov cx,12
       changes:mov byte ptr es:[bx],'0'
               add bx,2
    	   loop changes
    	   mov bx,160*10+40*0
    	   
           ch1:
               mov ah,0
    	   int 16h
    	   cmp ah,1ch
    	   je ch3
    
    	   cmp ah,0eh
    	   jne ch0
    	   cmp bx,640h
    	   je ch2
    
    	   dec bx
    	   dec bx
    	   mov byte ptr es:[bx],'0'
    	   jmp short ch2
           ch0:cmp bx,658h
    	   je ch2
    
    	   cmp ah,02h
    	   jb ch2
    	   cmp ah,0ah
    	   ja ch2
    	   mov byte ptr es:[bx],al
    	   add bx,2
           ch2:jmp short ch1
           ch3:
               mov cx,6
    	   mov dl,9
    	   mov bx,160*10+40*0
           ch4:push cx
               mov ax,es:[bx]
    	   sub ah,30h
    	   sub al,30h
               
    	   shl al,1
    	   shl al,1
    	   shl al,1
    	   shl al,1
    	   and ah,00001111b
    	   or al,ah
    	   mov ah,al
    	   
    	   mov al,dl
    	   out 70h,al
    	   mov al,ah
               out 71h,al
    	   add bx,4
    	   
    	   dec dl
    	   cmp bx,160*10+6
    	   je ce1
    	   ja ce2
    	   jna ce3
    
           ce2:inc dl
           ce1:sub dl,2
           ce3:pop cx
               loop ch4
    
    	   
               pop dx
               pop cx
               pop bx
    	   pop es
    	   pop ax
               ret
    
    code ends
    end begin
    
    
    
    

    功能选择是调用 int 16的0号功能,判断用户输入的数字在结合 cmp 和跳转指令去调用相关功能。

    而时钟程序中的符 f 1功能和 esc返回主菜单功能 是靠重写int 9 中断对其输入进行处理。
    在主程序中主菜单显示功能处有其调用标号,也有改变时钟颜色的调用语句及其调用处标号,
    在int 9 中先判断输入,如果输入为 f 1或 esc则分别在获得主程序中调用其功能处标号的段地址和偏移地址,想要去执行他们就要改变cs 和 ip就可以了,这时就可以利用int 9 中段中的 iret返回指令,其会把栈顶的两个元素设为cs 和 ip,所以可以把栈顶的元素换成先前保存的 主程序中调用f1
    功能和 esc 功能(显示主菜单)标号处的cs 和 ip。
    注意:
    (1)不要利用int 9 判断输入后直接call相关功能,因为这样你的int 9中段是没有执行完的,栈底会残留一开始中段过程压入的标志位寄存器和cs ip,因此多次调用int 9后会使栈发生溢出。
    (2)在重写int 9的时候在每次输入的时候如果不是 f1 或 esc则键盘缓冲区会把其保存下来,所以在esc返回主菜单中继续选择功能时利用无限循环先把键盘缓冲区要清理干净,再继续判断输入的功能号
    (3)因为实时显示时钟是靠循环读取cmos呈现的,所以显示时钟的子程序其ret指令是永远不会执行的,所以要在前面把call时压入栈的cs ip取出,防止多次调用其使栈发生溢出。
    (4)在改变时钟颜色时注意调用完颜色改变程序后就立刻去继续执行时钟显示程序,实现实时时钟颜色改变

  • 相关阅读:
    PHP常用时间函数总结
    LNMP 1.2缓存加速类扩展(xcache/Redis/memcached/eAccelerator)、imageMagick、ionCube安装教程
    LNMP强制https访问
    查看lnmp的编译参数和版本
    LNMP 1.2/1.3+升级Nginx、MySQL/MariaDB、PHP教程
    微信小程序websocket多页面冲突解决办法
    lnmp “.user.ini”无法删除解决方法
    一些js函数
    vue下拉框三级联动
    mysql取某个字段中的内容有等于数组中某个元素的数据
  • 原文地址:https://www.cnblogs.com/revercc/p/13287096.html
Copyright © 2020-2023  润新知