第9章 中断和动态时钟显示
本章的第一个代码功能是在屏幕中间实时显示时间,其实现的思想是: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章 中断和动态时钟显示相关推荐
- X86汇编语言从实模式到保护模式08:中断和动态时钟显示
目录 1. 外部硬件中断 1.1 概述 1.2 外部硬件中断分类 1.2.1 概述 1.2.2 不可屏蔽中断 1.2.3 可屏蔽中断 1.3 中断控制器 1.3.1 引入中断控制器的原因 1.3.2 ...
- 20、中断和动态时钟显示
文章目录 01.中断和硬件中断 02.中断控制器简介 03.中断号.中断处理过程.中断向量表 04.实时时钟.CMOS RAM和BCD编码 05.实时时钟芯片的中断信号 06.安装0x70号中断的处理 ...
- JavaScript实现动态时钟显示
目录 动态时钟显示效果 代码实现 1.创建html文件(时钟显示.html) 2.设置html标签 3.设置html标签的CSS样式 4.设置JavaScript 1)创建函数和Date 2)获取da ...
- Html5的Canva绘制动态时钟显示当前时间!!!(附源码)
前言 canvas设计一个显示当前时间的时钟 实现情况 思路 想让canvas绘制的东西动起来,最直接的办法就是不停的进行重绘,可能刚开始有些人会担心效率的问题,害怕代码过长冗余,可读性差的问题,实际 ...
- 蓝桥杯51单片机之数码管从点亮到动态时钟的实现【单片机开发初学者必掌握】
文章目录 一.点亮数码管 二.八位数码管同时从0到F 三.显示学号(指定数字) 四.中断机制的引入 五.利用中断实现动态时钟 一.点亮数码管 首先看一下案例源码: #include <reg52 ...
- python数码管动态时钟壁纸_8个动态数码管时钟显示
8 个动态数码管时钟显示 #include #define uint unsigned int #define uchar unsigned char uchar i,temp,aa,miao,fen ...
- Linux时间子系统之八:动态时钟框架(CONFIG_NO_HZ、tickless)【转】
转自:http://blog.csdn.net/droidphone/article/details/8112948 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 数据结构 ...
- 计算机原理与应用第七章——中断系统与Cortex-M微处理器的异常
第七章--中断系统与Cortex-M微处理器的异常 文章目录 第七章--中断系统与Cortex-M微处理器的异常 一.异常和中断的基本概念 (一)中断源 (二)中断管理 (三)中断优先级管理 (四)中 ...
- javascript 计算器、动态时钟、表格复选框全选(扩展)、轮播图、36选7、随机数...
<!doctype html> <html> <head> <meta charset="utf-8"> <title> ...
最新文章
- 博客域名改为http://bobli.cnblogs.com
- 独家 | Deepnote测评:数据科学家的新IDE
- 简单的表单提交 by MVC 2
- FreeRTOS系列第1篇---为什么选择FreeRTOS?
- 互联网1分钟 | 0327 华为P30系列发布;微信公号直播工具大范围开放内测资格
- BZOJ4856 JSOI2016 病毒感染 区间DP
- 使用fn函数控制页面显示内容
- 一切都是关于“ –ilities”的
- python 列表的推导器和内置函数
- java 正则 第一个出现的字符_如何用正则表达式通过第一个出现的字符进行拆分?...
- 4. Browser 对象 - Navigator 对象(2)
- 深度原理与框架-图像超分辨重构-tensorlayer
- 一个android本地txt阅读器的思路与实现
- matlab 线型、标记、颜色
- 数据链路层之以太网、MAC、MTU详解
- Java各种学习资源(视频+文档)
- 微服务设计指导-使用云原生微服务解决传统海量跑批时引起的系统间“级联雪崩”以及效率
- 设计师都爱用的UI标注软件有哪些?
- Elasticsearch JestClient 使用
- 二篇、使用excel做数据驱动把数据管理起来
热门文章
- spring mvc学习(11):eclipse的环境maven项目创建前期工作
- 单实例数据库和多实例数据库
- KEIL5 编译器导致的程序异常
- STM32的I2C主从机通信
- vue项目发布时去除console语句
- CSS 相对|绝对(relative/absolute)定位系列(二)
- python网站模板下载_Python画图模板大全:从此画图不用愁
- java lambda if_使用Java8的Lambda实现Monda -解道Jdon
- LOJ 2979 「THUSCH 2017」换桌——多路增广费用流
- Python---通配符的使用