第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是怎样工作的,明白了程序的底层,这就是通过语言学到的理念。

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













本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/421003.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 架构

最内层是我们的硬件,最外层是我们常用的各种应用,比如说使用firefox浏览器,打开evolution查看邮件,运行一个计算流体模型等等。硬件是我们的物质基础,而应用是我们所要奋斗的目标,但在两者之间,…

py学习,列表,判断,循环

列表 1.1 列表是什么 python 中可以通过组合一些值得到多种复合数据类型。其中最常用的是列表,可以通过方括号括起,逗号分隔的一组值(元素)得到,一个列表可以包含不同类型的元素,一个列表的元素各个类型相同…

现代软件工程讲义 3 代码规范与代码复审

请参考原址:http://www.cnblogs.com/xinz/archive/2011/11/20/2255971.html 第10章 代码规范与代码复审 在第9章中,同学们完成了WC程序,经过评比,九条的程序获得了第一名。这时,阿超说,现代软件产业经过几十…

HDU 2159 FATE (DP 二维费用背包)

题目链接 题意 : 中文题不详述。 思路 : 二维背包,dp[i][h]表示当前忍耐值为i的情况下,杀了h个怪得到的最大经验值,状态转移方程: dp[i][h] max(dp[i][h],dp[i-a[j].toler][h-1]a[j].exper) ; 1 //21592 #…

TinyFrame升级之五:全局缓存的设计及实现

在任何框架中,缓存都是不可或缺的一部分,本框架亦然。在这个框架中,我们的缓存分为两部分:内存缓存和单次请求缓存。简单说来,就是一个使用微软提供的MemoryCache做扩展,并提供全局唯一实例;另一…

问题思维导向

杨淼信息与计算机科学 跆拳道国家一级教练员 曾经tricking爱好者3 人赞同了该回答一个不算建议的建议 直接看,看到不懂的就查相应的知识(据说牛人都靠wiki活着)。 知识当有需求的时候,才会学的更快。 觉得这样做的好处是&#xff…

【Mail】telnet收发邮件过程

文章原址:http://www.cnblogs.com/h--d/p/6125993.html 作者写的真棒,按照步骤一步一步都可执行,我是在centos7服务器下进行的实验,命令完全和下面一样,注意的地方是: 1,centos7要安装telnet&a…

入门训练 Fibonacci数列

http://lx.lanqiao.org/problem.page?gpidT4入门训练 Fibonacci数列 时间限制:1.0s 内存限制:256.0MB问题描述Fibonacci数列的递推公式为:FnFn-1Fn-2,其中F1F21。 当n比较大时,Fn也非常大,现在我们想知…

python模块与包的导入

一&#xff0c;模块 1&#xff0c;下面是hello.py脚本(模块)&#xff0c;有两求Fibonacci的函数. def fib1():a, b 0, 1print(0-10内:)while a < 10:print(a, end )a, b b, a bprint()def fib2(n):a, b 0, 1L []while a < n:L.append(a)a, b b, a bprint(L)retu…

第11章 进入保护模式

对照代码重点理解一下三个要点&#xff1a; 1,从实模式到保护模式的整体过程&#xff1b; 2&#xff0c;实模式怎样安装GDT&#xff1b; 3&#xff0c;从实模式怎样过渡到安全模式&#xff1b; 4&#xff0c;安全模式怎样寻址&#xff1b; 代码如下&#xff1a; ;代码清单1…

ASP.NET学习笔记之操作过滤器

转载于:https://www.cnblogs.com/kevin1988/p/3684442.html

第12章 存储器的保护

学习32位保护模式明显感觉比16位实模式复杂一些&#xff0c;其实两者之间所做的事情是一样的&#xff0c;无非是对内存的各种操作&#xff0c;对栈的各种操作&#xff0c;但是手段不一样&#xff0c;实模式是野蛮的&#xff0c;可以在任意地方读写&#xff08;比如代码区&#…

with open的使用

1, open(‘file’, mode) 第一个参数是包含文件名的字符串。第二个参数是另一个字符串&#xff0c;其中包含一些描述文件使用方式的字符。mode 可以是 ‘r’&#xff0c;表示文件只能读取&#xff0c;‘w’ 表示只能写入&#xff08;已存在的同名文件会被删除&#xff09;&…

Android硬件抽象层(HAL)概要介绍和学习计划 1转

最近和另外一家开发公司涉及到合作,一直希望了解Android从Linux到App整个架构和流程,那家开发工程师也不断提供帮助,不过如果借助后面几篇博客,相对系统和完整的可以了解更加清晰, <博客:http://blog.csdn.net/luoshengyang/article/details/6567257> Android的硬件抽象层…

第13章 程序的动态加载和执行(二,用户代码)

弄清楚两个问题&#xff0c;这段应用代码就容易读懂了&#xff1a; 1&#xff0c;核心代码是如何把指针指到这里的&#xff1b; 2&#xff0c;这段代码是如何使用内存的&#xff1b; 读这个代码的时候&#xff0c;可以类比我们平时写的练习小程序&#xff0c;以C程序为例&am…

【雷军】给程序员的五点建议--如何成为编程高手并以此创业

除非特别注明&#xff0c;鸡啄米文章均为原创转载请标明本文地址&#xff1a;http://www.jizhuomi.com/career/286.html写在前面&#xff1a;此篇文章出自雷军之手&#xff0c;是他为软件开发2.0技术大会准备的演讲稿&#xff0c;但由于某些原因没有派上用场。这里跟大家分享下…

计算机网络重要机制(一)可靠数据传输

操作系统&#xff0c;计算机网络都属于计算机系统&#xff0c;为了使得整个系统运行起来&#xff0c;人们根据当时的硬件条件和理论认识设计了各种的算法&#xff08;也可以叫机制&#xff09;&#xff0c;这些机制有些被抛弃&#xff0c;有些被进化。所以操作系统、计算机网络…