外中断02 - 零基础入门学习汇编语言70

第十五章:外中断02

 

让编程改变世界

Change the world by program


 

小甲鱼和大家谈谈心

  一个帖子引发小甲鱼的反省! 猫姐曾经说过,步子别迈太大,容易扯着蛋! 结果还真蛋疼了……   因此,小甲鱼要学会淡定面对,不能忘记当初的宗旨!做视频也好、做网站也好,对得住大家才对得住自己的良心! 最后:希望大家继续支持鱼C、支持小甲鱼,看到大家都能坦诚相待,很开心,很幸福!  

编写int 9 中断例程

 

复习一下前边的内容中,我们可以总结出键盘输入的处理过程:

(1)键盘产生扫描码; (2)扫描码送入60h 端口; (3)一旦侦测到60h端口有动静,引发9 号中断; (4)CPU执行int 9 中断例程处理键盘输入。 以上的过程,前三步都由硬件系统自动完成。我们能够改变的只有第四步,修改int 9 终端程序。 但是,在这门课程中,我们不准备完整地编写一个键盘中断的处理程序,因为要涉及到一些硬件细节,而这些内容脱离了我们的内容主线。 插入语:如果有兴趣想更为深入的学习汇编语言,探究汇编语言的奥妙,可以关注小甲鱼今后推出的《The Art of Assembly Language》。  

但是,我们却还要编写新的键盘中断处理程序,来进行一些特殊的工作,那么这些硬件细节如何处理呢?

如果单纯要完成这点还是相对比较简单的,因为BIOS 提供的int 9中断例程已经对这些硬件细节进行了处理。 我们只要在自己编写的中断例程中调用BIOS 的int 9中断例程就可以了。  

任务演示:在屏幕中间依次显示 “a”~“z” ,并可以让人看清。在显示的过程中,按下Esc键后,改变显示的颜色。

 

我们先来看一下如何依次显示“a”~“z”:

[codesyntax lang="asm"]
	assume cs:codecode segmentstart:    mov ax,0b800hmov es,axmov ah,'a's:   mov es:[160*12+40*2],ahinc ahcmp ah,'z'jna smov ax,4c00hint 21hcode endsend start
[/codesyntax]   我们发觉,因为一个字母刚显示到屏幕上,CPU执行几条指令后,就又变成了另一个字母,字母之间切换得太快,因此我们无法看清。 理想状况是:我们应该在每显示一个字母后,延时一段时间,让人看清后,再显示下一个字母。  

那么如何延时呢?

不如……我们让CPU 执行一段时间的空循环。有时候让它做点无用功哈~   请看源代码并试图分析作者的做法:相关代码下载   现在显示“a”~“z”的任务我们基本完成了,并做到可以让人看清,虽然做法有些无耻……   那么接下来将进一步来实现:按下 Esc 键后,改变显示的颜色!怎么办呢? 键盘输入到达60h 端口后,就会引发 9号中断,CPU 则转去执行int 9中断例程。   我们可以编写int 9中断例程,功能如下: (1)从60h端口读出键盘的输入; (2)调用BIOS 的int 9 中断例程,处理其他硬件细节; (3)判断是否为Esc的扫描码,如果是,改 变显示的颜色后返回;如果不是则直接返回。    

接下来,我们对这些功能的实现一一进行分析!

 

第一步:从端口60h读出键盘的输入

in al,60h  

第二步:调用BIOS的int 9中断例程

注:有一点要注意的是,我们写的中断处理程序要成为新的int 9中断例程,主程序必须要将中断向量表中的int 9中断例程的入口地址改为我们写的中断处理程序的入口地址。 那么在新的中断处理程序中调用原来的int 9中断例程时,中断向量表中的int 9中断例程的入口地址却不是原来的int 9 中断例程的地址。所以我们不能使用int 指令直接调用。   这里有必要解释一下:。。。。。。 对于我们现在的问题,假设我们将原来int 9中断例程的偏移地址和段地址保存在ds:[0]和ds:[2]单元中。 那么我们在需要调用原来的int 9中断例程时候,就可以在 ds:[0]、ds:[2] 单元中找到它的入口地址。  

那么,有了入口地址后,我们如何进行调用呢?

当然不能使用指令int 9来调用。我们可以用别的指令来对int指令进行一些模拟,从而实现对中断例程的调用。   我们来看,int 指令在执行的时候,CPU 进行下面的工作: (1)取中断类型码n; (2)标志寄存器入栈; (3) IF=0,TF=0; (4) CS 、IP 入栈; (5)(IP) = (n*4),(CS) = (n*4+2)。 取中断类型码是为了定位中断例程的入口地址,在我们的问题中,中断例程的入口地址已经知道。 所以,我们用别的指令模拟int 指令时候,不需要做第(1)步。   在假设要调用的中断例程的入口地址在ds:0和ds:2单元中的前提下,我们将int 过程用下面几步模拟: (1)标志寄存器入栈; (2)IF=0,TF=0; (3)CS、IP入栈; (4)(IP)=((ds)*16+0),(CS)=((ds)*16+2)。 可以注意到第(3)、(4)步和call dword ptr ds:[0]的功能一样。   call dword ptr ds:[0] 的功能也是: (1)CS 、IP 入栈; (2)(IP)=((ds)*16+0),(CS)=((ds)*16+2)。 如果这点上有疑问的童鞋,不妨可以复习下10.6节的内容。  

所以经过我们总结后,int 过程的模拟最终变为:

(1)标志寄存器入栈; (2)IF=0,TF=0; (3)call dword ptr ds:[0] 对于(1),可用pushf实现。 对于(2),我们又得动点歪脑筋,没办法,资源条件极其卑劣的8086 要么使人放弃,要么逼出天才!我们可用以下程序间接实现:   实现IF=0,TF=0步骤:

pushf

pop ax

and ah,11111100b ; IF和OF为标志寄存器的

; 第9位和第8位

push ax

popf

  这样,模拟int指令的调用功能,调用入口地址在ds:0、ds:2中的中断例程的程序如下:

pushf ;标志寄存器入栈

pushf

pop ax

and ah,11111100b ; IF和OF为标志寄存器的第9

; 位和第8位

push ax

popf ;IF=0、TF=0

call dword ptr ds:[0]

 

第三步:如果是Esc键的扫描码,改变显示的颜色后返回……

  那么,下一个问题:如何改变显示的颜色? [buy] 获得所有教学视频、课件、源代码等资源打包 [/buy] [Downlink href='http://kuai.xunlei.com/d/LWPDSCJPSSUD']视频下载[/Downlink]

转载于:https://www.cnblogs.com/LoveFishC/archive/2011/05/27/3846090.html

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

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

相关文章

蛇形填数

描述 在n*n方阵里填入1,2,…,n*n,要求填成蛇形。例如n4时方陈为&#xff1a; 10 11 12 1 9 16 13 2 8 15 14 3 7 6 5 4 输入 直接输入方陈的维数&#xff0c;即n的值。(n<100) 输出 输出结果是蛇形方陈。 样例输入 3 样例输出 7 8 1 6 9 2 5 4 3 代码如下 …

c#数组获取元素的索引_获取元素集合 从C#中的指定索引

c#数组获取元素的索引Given a Collection<T> of integer types, and an index, we have to access the element from the given index. 给定一个整数类型的Collection <T>和一个索引&#xff0c;我们必须从给定索引访问元素。 To access an element of the Collec…

linux清理缓存cache,Linux清理cache缓存

当cache缓存占用太大&#xff0c;服务起不来&#xff0c;需要查看清理缓存查看缓存&#xff1a;free -m输入运行下面一行&#xff1a;echo 3 > /proc/sys/vm/drop_caches# 释放缓存区内存的方法1)清理pagecache(页面缓存)# echo 1 > /proc/sys/vm/drop_caches 或者 # sys…

c和汇编混合编程----shellcode----弹出计算器

先用c和汇编混合编程成功弹出计算器&#xff08;在VC里运行&#xff09; #include "stdio.h" #include "windows.h"int main(int argc, char* argv[]) {printf("begin\n");HINSTANCE libHandle;char *dll"kernel32.dll";libHandleLoa…

[导入]转:世界小姐形容他们国家male organ

世界小姐眼中的最后一问&#xff1a;形容一下他们国家male organMiss Universes last Question 环球小姐最后一题 Question: Ms America, how do you describe a male organ in your country? 问&#xff1a;美国小姐&#xff0c;请形容贵国男性的性器官。Ms America: Well, I…

scala字符串替换_如何在Scala中替换字符串中的正则表达式模式?

scala字符串替换Scala | 替换字符串中的正则表达式模式 (Scala | Replacing a regular expression pattern in a string) Replacing a part of the string that matches our given regular expression can be done using multiple methods. 可以使用多种方法替换匹配给定正则表…

有趣的数

描述 把分数按下面的办法排成一个数表。 ① ② ⑥ ⑦ 1/1 1/2 1/3 1/4… ③ ⑤ ⑧ 2/1 2/2 2/3… ④ ⑨ 3/1 3/2 … ⑩ 4/1… … 我们以z字型方法给上表的每项编号。特定方法&#xff1a;第一项是1/1&#xff0c;然后是1/2、2/1、3/1、2/2、1/3、1/4、2/3……。编程输入项号N&…

linux系统的层次结构,关于Linux操作系统层次结构分析

本文转自http://www.jb51.net/LINUXjishu/214104.html首先来看一张图(这是Linux操作系统的大致层次结构)&#xff1a;最内层是硬件&#xff0c;最外层是用户常用的应用&#xff0c;比如说firefox浏览器&#xff0c;evolution查看邮件&#xff0c;一个计算流体模型等等。硬件是物…

Windows Vista版本比较

Windows Vista上市在即&#xff0c;对许多朋友来说目前急待解决的问题便是&#xff0c;在升级或购买时应该选择Windows Vista的哪个版本&#xff0c;哪个版本更契合自己的应用需求&#xff0c;究竟应该选择Windows Vista Home呢还是Windows Vista Ultimate?等等。 之前在Windo…

shellcode---c和汇编混合编程---弹出cmd

首先用C/C语言实现弹出cmd #include "stdio.h" #include "windows.h"int main(int argc, char* argv[]) {printf("begin\n");HINSTANCE libHandle;char *dll"kernel32.dll";libHandleLoadLibrary(dll);WinExec("cmd.exe",S…

ajax 复制到“剪贴板”

有时候可能会做一些“复制”按钮的功能&#xff0c;当用户点击“复制”按钮时&#xff0c;就会将要复制的内容复制出来&#xff0c;以下代码即实现“复制”按钮的功能。该功能需要用到AJAX的PageMethods来调用页面后台代码来实现。 调用PageMethods&#xff0c;需要引用 <sc…

找到最大回文子串_使用O(1)空间复杂度找到最大的回文子串

找到最大回文子串Problem statement: 问题陈述&#xff1a; Given a string, you have to find the largest palindromic substring using O(1) space complexity. 给定一个字符串&#xff0c;您必须使用O(1)空间复杂度找到最大的回文子字符串。 Input:T Test caseT no of in…

日期计算

描述 如题&#xff0c;输入一个日期&#xff0c;格式如&#xff1a;2010 10 24 &#xff0c;判断这一天是这一年中的第几天。 输入 第一行输入一个数N&#xff08;0< N<100&#xff09;,表示有N组测试数据。后面的N行输入多组输入数据&#xff0c;每行的输入数据都是一个…

c语言程序设计编程解读,【答题】C语言程序设计问题与解释实验

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼#include#define N 13main(){int y,m,D,q,t0,i,day0,a0,Day,n,k,O[N]{0,31,29,31,30,31,30,31,31,30,31,30,31},p[N]{0,31,28,31,30,31,30,31,31,30,31,30,31};//y是年&#xff0c;m是月&#xff0c;D是日&#xff0c;q计算周几&am…

blog的转变

从技术为主的blog&#xff0c;变为记录生活琐事的blog&#xff0c;OMG&#xff01;天气晴朗&#xff0c;不过心情并不怎么轻松&#xff0c;论文下周必须要写完&#xff0c;同时留校结果也就该出来了。曾经一度以为&#xff0c;一个人最快乐自由。不过不得不承认&#xff0c;或许…

没有值的json字符串_Java中具有原始数据类型值的字符串连接

没有值的json字符串Given a string and some of the primitive data type values, we have to concatenate them with the string in Java. 给定一个字符串和一些原始数据类型值&#xff0c;我们必须将它们与Java中的字符串连接起来。 In the example below, we have declared…

a letter and a number(一封信和一个数字)

描述 we define f(A) 1, f(a) -1, f(B) 2, f(b) -2, … f(Z) 26, f(z) -26; Give you a letter x and a number y , you should output the result of yf(x). 我们定义f ( A ) 1&#xff0c;f ( A ) - 1&#xff0c;f ( B ) 2&#xff0c;f ( B ) - 2&#xff0c;…

c语言初始化字符数组为空,怎么把已经初始化的字符数组设置为空?

怎么把已经初始化的字符数组设置为空&#xff1f;两种方法&#xff0c;如下所示。方法一&#xff1a;代码演示#include #include int main(void){char a[]{x,y,z}; //定义字符数组&#xff0c;并初始化int i0;for(i0;i<3;i)printf("%c\t",a[i]); //输出初始化的数…

C和汇编混合编程---栈平衡

最近在搞C和汇编混合编程&#xff0c;对栈平衡有点小理解&#xff0c;记录一下 当我们调用一个API或者子程序时时&#xff0c;API和子程序可以理解为函数&#xff0c;我们不必在返回的时候平衡栈里面的函数参数&#xff0c;但C语言库函数要我们自己平衡栈数据&#xff0c; 比如…

[导入]2006年10大变态站名网站排名

作者&#xff1a; 马国良 | 2006年11月14日13时31分 | 【内容提要】第一名&#xff1a;妈妈说…… 入选原因&#xff1a;单看了两个域名就让人觉得变态“妈妈说就算你注册的域名再长google都能搜索出来”(mamashuojiusuannizhucedeyumingzaichanggoogledounengsousuochulai.cn)…