本章的第一个代码功能是在屏幕中间实时显示时间,其实现的思想是:cpu停机---》时间每秒更新一次,每一次更新都会引起0x70中断(0x70中断的内容已经被我们更改为显示当前时间)---》中断唤醒cpu开始执行我们的中断程序知道结束---》CPU停机等待中断---》唤醒CPU。。。

本程序的难点在于对8259芯片的理解和设置,这件事重要但不紧急,一时理解不通可以暂时跳过去。

         ;代码清单9-1;文件名:c09_1.asm;文件说明:用户程序 ;创建日期:2011-4-16 22:03;===============================================================================
SECTION header vstart=0                     ;定义用户程序头部段 program_length  dd program_end          ;程序总长度[0x00];用户程序入口点code_entry      dw start                ;偏移地址[0x04]dd section.code.start   ;段地址[0x06] realloc_tbl_len dw (header_end-realloc_begin)/4;段重定位表项个数[0x0a]realloc_begin:;段重定位表           code_segment    dd section.code.start   ;[0x0c]data_segment    dd section.data.start   ;[0x14]stack_segment   dd section.stack.start  ;[0x1c]header_end:                ;===============================================================================
SECTION code align=16 vstart=0           ;定义代码段(16字节对齐)
new_int_0x70:push axpush bxpush cxpush dxpush es.w0:                                    mov al,0x0a                        ;阻断NMI。当然,通常是不必要的or al,0x80                          out 0x70,alin al,0x71                         ;读寄存器Atest al,0x80                       ;测试第7位UIP jnz .w0                            ;以上代码对于更新周期结束中断来说 ;是不必要的 xor al,alor al,0x80out 0x70,alin al,0x71                         ;读RTC当前时间(秒)push axmov al,2or al,0x80out 0x70,alin al,0x71                         ;读RTC当前时间(分)push axmov al,4or al,0x80out 0x70,alin al,0x71                         ;读RTC当前时间(时)push axmov al,0x0c                        ;寄存器C的索引。且开放NMI out 0x70,alin al,0x71                         ;读一下RTC的寄存器C,否则只发生一次中断;此处不考虑闹钟和周期性中断的情况 mov ax,0xb800mov es,axpop axcall bcd_to_asciimov bx,12*160 + 36*2               ;从屏幕上的12行36列开始显示mov [es:bx],ahmov [es:bx+2],al                   ;显示两位小时数字mov al,':'mov [es:bx+4],al                   ;显示分隔符':'not byte [es:bx+5]                 ;反转显示属性 pop axcall bcd_to_asciimov [es:bx+6],ahmov [es:bx+8],al                   ;显示两位分钟数字mov al,':'mov [es:bx+10],al                  ;显示分隔符':'not byte [es:bx+11]                ;反转显示属性pop axcall bcd_to_asciimov [es:bx+12],ahmov [es:bx+14],al                  ;显示两位小时数字mov al,0x20                        ;中断结束命令EOI out 0xa0,al                        ;向从片发送 out 0x20,al                        ;向主片发送 pop espop dxpop cxpop bxpop axiret;-------------------------------------------------------------------------------
bcd_to_ascii:                            ;BCD码转ASCII;输入:AL=bcd码;输出:AX=asciimov ah,al                          ;分拆成两个数字 and al,0x0f                        ;仅保留低4位 add al,0x30                        ;转换成ASCII shr ah,4                           ;逻辑右移4位 and ah,0x0f                        add ah,0x30ret;-------------------------------------------------------------------------------
start:mov ax,[stack_segment]mov ss,axmov sp,ss_pointermov ax,[data_segment]mov ds,axmov bx,init_msg                    ;显示初始信息 call put_stringmov bx,inst_msg                    ;显示安装信息 call put_stringmov al,0x70mov bl,4mul bl                             ;计算0x70号中断在IVT中的偏移mov bx,ax                          cli                                ;防止改动期间发生新的0x70号中断push esmov ax,0x0000mov es,axmov word [es:bx],new_int_0x70      ;偏移地址。mov word [es:bx+2],cs              ;段地址pop esmov al,0x0b                        ;RTC寄存器Bor al,0x80                         ;阻断NMI out 0x70,almov al,0x12                        ;设置寄存器B,禁止周期性中断,开放更 out 0x71,al                        ;新结束后中断,BCD码,24小时制 mov al,0x0cout 0x70,alin al,0x71                         ;读RTC寄存器C,复位未决的中断状态in al,0xa1                         ;读8259从片的IMR寄存器 and al,0xfe                        ;清除bit 0(此位连接RTC)out 0xa1,al                        ;写回此寄存器 sti                                ;重新开放中断 mov bx,done_msg                    ;显示安装完成信息 call put_stringmov bx,tips_msg                    ;显示提示信息call put_stringmov cx,0xb800mov ds,cxmov byte [12*160 + 33*2],'@'       ;屏幕第12行,35列.idle:hlt                                ;使CPU进入低功耗状态,直到用中断唤醒not byte [12*160 + 33*2+1]         ;反转显示属性 jmp .idle;-------------------------------------------------------------------------------
put_string:                              ;显示串(0结尾)。;输入:DS:BX=串地址mov cl,[bx]or cl,cl                        ;cl=0 ?jz .exit                        ;是的,返回主程序 call put_charinc bx                          ;下一个字符 jmp put_string.exit:ret;-------------------------------------------------------------------------------
put_char:                                ;显示一个字符;输入:cl=字符asciipush axpush bxpush cxpush dxpush dspush es;以下取当前光标位置mov dx,0x3d4mov al,0x0eout dx,almov dx,0x3d5in al,dx                        ;高8位 mov ah,almov dx,0x3d4mov al,0x0fout dx,almov dx,0x3d5in al,dx                        ;低8位 mov bx,ax                       ;BX=代表光标位置的16位数cmp cl,0x0d                     ;回车符?jnz .put_0a                     ;不是。看看是不是换行等字符 mov ax,bx                       ; mov bl,80                       div blmul blmov bx,axjmp .set_cursor.put_0a:cmp cl,0x0a                     ;换行符?jnz .put_other                  ;不是,那就正常显示字符 add bx,80jmp .roll_screen.put_other:                             ;正常显示字符mov ax,0xb800mov es,axshl bx,1mov [es:bx],cl;以下将光标位置推进一个字符shr bx,1add bx,1.roll_screen:cmp bx,2000                     ;光标超出屏幕?滚屏jl .set_cursormov ax,0xb800mov ds,axmov es,axcldmov si,0xa0mov di,0x00mov cx,1920rep movswmov bx,3840                     ;清除屏幕最底一行mov cx,80.cls:mov word[es:bx],0x0720add bx,2loop .clsmov bx,1920.set_cursor:mov dx,0x3d4mov al,0x0eout dx,almov dx,0x3d5mov al,bhout dx,almov dx,0x3d4mov al,0x0fout dx,almov dx,0x3d5mov al,blout dx,alpop espop dspop dxpop cxpop bxpop axret;===============================================================================
SECTION data align=16 vstart=0init_msg       db 'Starting...',0x0d,0x0a,0inst_msg       db 'Installing a new interrupt 70H...',0done_msg       db 'Done.',0x0d,0x0a,0tips_msg       db 'Clock is now working.',0;===============================================================================
SECTION stack align=16 vstart=0resb 256
ss_pointer:;===============================================================================
SECTION program_trail
program_end:

实验现象:

体会:作为工程性的学科,学习底层的东西就是学习历史,中间包含的不只是科学原因,还有当时的历史原因,里面有很多现在看来怪异的现象。

实验二

代码45~46行,在这里,当寄存器 AH 的内容是 0x00 时,执行 int 0x16 后,中断服务例程会监视键盘动作。当它返回时,会在寄存器 AL 中存放按键的 ASCII 码。假如 键盘没有什么动作,则cs:ip会一直陷在int 0x16中断中,直到有动作。

         ;代码清单9-2;文件名:c09_2.asm;文件说明:用于演示BIOS中断的用户程序 ;创建日期:2012-3-28 20:35;===============================================================================
SECTION header vstart=0                     ;定义用户程序头部段 program_length  dd program_end          ;程序总长度[0x00];用户程序入口点code_entry      dw start                ;偏移地址[0x04]dd section.code.start   ;段地址[0x06] realloc_tbl_len dw (header_end-realloc_begin)/4;段重定位表项个数[0x0a]realloc_begin:;段重定位表           code_segment    dd section.code.start   ;[0x0c]data_segment    dd section.data.start   ;[0x14]stack_segment   dd section.stack.start  ;[0x1c]header_end:                ;===============================================================================
SECTION code align=16 vstart=0           ;定义代码段(16字节对齐)
start:mov ax,[stack_segment]mov ss,axmov sp,ss_pointermov ax,[data_segment]mov ds,axmov cx,msg_end-messagemov bx,message.putc:              ;该功能用于在屏幕上的光标位置处写一个字符,并推进光标位置mov ah,0x0emov al,[bx]int 0x10inc bxloop .putc.reps:mov ah,0x00int 0x16mov ah,0x0emov bl,0x07   ;bl前景色,但是设置了也没用???[yb]int 0x10jmp .reps;===============================================================================
SECTION data align=16 vstart=0message       db 'Hello, friend!',0x0d,0x0adb 'This simple procedure used to demonstrate 'db 'the BIOS interrupt.',0x0d,0x0adb 'Please press the keys on the keyboard ->'msg_end:;===============================================================================
SECTION stack align=16 vstart=0resb 256
ss_pointer:;===============================================================================
SECTION program_trail
program_end:

实验现象:

实验体会:

计算机的学习类似于学习英语,在语言中学习西方的思想和文化,同样,在计算机程序语言中学习计算机的设计理念和概念,这就是《像计算机学家一样思考Python》一书所倡导的学习理念,在程序中去学习,可以是数学可以是操作系统可以是网络,一个一个的问题解决,最后什么看似深刻的原理都明白了;

通过学习汇编语言,明白了cpu是怎样工作的,明白了程序的底层,这就是通过语言学到的理念。

不难,多看,多思考,多总结。

第9章 中断和动态时钟显示相关推荐

  1. X86汇编语言从实模式到保护模式08:中断和动态时钟显示

    目录 1. 外部硬件中断 1.1 概述 1.2 外部硬件中断分类 1.2.1 概述 1.2.2 不可屏蔽中断 1.2.3 可屏蔽中断 1.3 中断控制器 1.3.1 引入中断控制器的原因 1.3.2 ...

  2. 20、中断和动态时钟显示

    文章目录 01.中断和硬件中断 02.中断控制器简介 03.中断号.中断处理过程.中断向量表 04.实时时钟.CMOS RAM和BCD编码 05.实时时钟芯片的中断信号 06.安装0x70号中断的处理 ...

  3. JavaScript实现动态时钟显示

    目录 动态时钟显示效果 代码实现 1.创建html文件(时钟显示.html) 2.设置html标签 3.设置html标签的CSS样式 4.设置JavaScript 1)创建函数和Date 2)获取da ...

  4. Html5的Canva绘制动态时钟显示当前时间!!!(附源码)

    前言 canvas设计一个显示当前时间的时钟 实现情况 思路 想让canvas绘制的东西动起来,最直接的办法就是不停的进行重绘,可能刚开始有些人会担心效率的问题,害怕代码过长冗余,可读性差的问题,实际 ...

  5. 蓝桥杯51单片机之数码管从点亮到动态时钟的实现【单片机开发初学者必掌握】

    文章目录 一.点亮数码管 二.八位数码管同时从0到F 三.显示学号(指定数字) 四.中断机制的引入 五.利用中断实现动态时钟 一.点亮数码管 首先看一下案例源码: #include <reg52 ...

  6. python数码管动态时钟壁纸_8个动态数码管时钟显示

    8 个动态数码管时钟显示 #include #define uint unsigned int #define uchar unsigned char uchar i,temp,aa,miao,fen ...

  7. Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)【转】

    转自:http://blog.csdn.net/droidphone/article/details/8112948 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 数据结构 ...

  8. 计算机原理与应用第七章——中断系统与Cortex-M微处理器的异常

    第七章--中断系统与Cortex-M微处理器的异常 文章目录 第七章--中断系统与Cortex-M微处理器的异常 一.异常和中断的基本概念 (一)中断源 (二)中断管理 (三)中断优先级管理 (四)中 ...

  9. javascript 计算器、动态时钟、表格复选框全选(扩展)、轮播图、36选7、随机数...

    <!doctype html> <html> <head> <meta charset="utf-8"> <title> ...

最新文章

  1. 博客域名改为http://bobli.cnblogs.com
  2. 独家 | Deepnote测评:数据科学家的新IDE
  3. 简单的表单提交 by MVC 2
  4. FreeRTOS系列第1篇---为什么选择FreeRTOS?
  5. 互联网1分钟 | 0327 华为P30系列发布;微信公号直播工具大范围开放内测资格
  6. BZOJ4856 JSOI2016 病毒感染 区间DP
  7. 使用fn函数控制页面显示内容
  8. 一切都是关于“ –ilities”的
  9. python 列表的推导器和内置函数
  10. java 正则 第一个出现的字符_如何用正则表达式通过第一个出现的字符进行拆分?...
  11. 4. Browser 对象 - Navigator 对象(2)
  12. 深度原理与框架-图像超分辨重构-tensorlayer
  13. 一个android本地txt阅读器的思路与实现
  14. matlab 线型、标记、颜色
  15. 数据链路层之以太网、MAC、MTU详解
  16. Java各种学习资源(视频+文档)
  17. 微服务设计指导-使用云原生微服务解决传统海量跑批时引起的系统间“级联雪崩”以及效率
  18. 设计师都爱用的UI标注软件有哪些?
  19. Elasticsearch JestClient 使用
  20. 二篇、使用excel做数据驱动把数据管理起来

热门文章

  1. spring mvc学习(11):eclipse的环境maven项目创建前期工作
  2. 单实例数据库和多实例数据库
  3. KEIL5 编译器导致的程序异常
  4. STM32的I2C主从机通信
  5. vue项目发布时去除console语句
  6. CSS 相对|绝对(relative/absolute)定位系列(二)
  7. python网站模板下载_Python画图模板大全:从此画图不用愁
  8. java lambda if_使用Java8的Lambda实现Monda -解道Jdon
  9. LOJ 2979 「THUSCH 2017」换桌——多路增广费用流
  10. Python---通配符的使用