码农知识堂 - 1000bd
  •   Python
  •   PHP
  •   JS/TS
  •   JAVA
  •   C/C++
  •   C#
  •   GO
  •   Kotlin
  •   Swift
  • 汇编语言中断及外部设备操作篇--06


    汇编语言中断及外部设备操作篇--06

    • 移位指令
      • 示例:逻辑移位指令shl和shr
    • 操作显存数据
      • 显示的原理
      • 显示缓冲区的结构
      • 显示信息的一种“直接”方式
    • 描述内存单元的标号
      • 关于标号
      • 去了冒号的数据标号
      • 数据标号同时描述内存地址和单元长度
      • 更常见的方式:数据段中的数据标号
    • 数据的直接定址表
      • 直接定址表:用查表的方法解决问题
      • 最简解决方案
      • 直接定址表
      • 应用示例:为加快运算速度而采用查表方法
        • 解决方案
    • 代码的直接定址表
      • 使用代码的直接定址表解决问题
      • 各种功能的实现
      • 直接写址表的优势
    • 中断及其处理
      • 中断的概念
      • 8086的内中断
      • 中断处理程序
      • 案例:系统中的0号中断
      • 中断过程
    • 编制中断处理程序
      • 中断处理程序及其结构
      • 编制中断处理程序——以除法错误中断为例
        • do0子程序应该放在哪里?
        • 程序框架
        • do0安装程序的实现
        • do0子程序的实现
        • 小结
    • 单步中断
      • 由Debug中的t命令说起……
      • 单步中断过程与处理
      • 应用:中断不响应的情况
    • 由int指令引发的中断
      • int n引起的中断
      • 编写供应用程序调用的中断例程
        • 示例 :中断7ch的中断例程
    • BIOS和DOS中断处理
      • BIOS——基本输入输出系统
      • BIOS中断调用示例
      • 有哪些BIOS中断,怎么用?
      • 汇编的强大功能,还有DOS中断!
      • int 21HDOS 中断例程的应用
      • BIOS和DOS中断例程的安装过程
    • 端口的读写
      • 用端口访问外设:以发声为例
      • CPU的邻居
      • 端口的读写
      • 端口的读写过程演示
      • I/O端口分配
      • 端口的读写指令示例
    • 操作CMOS RAM芯片
      • CMOS RAM 芯片
      • 端口操作示例:提取CMOS RAM中存储的时间信息
      • 在屏幕中间显示当前的月份
    • 外设连接与中断
      • CPU通过端口与外部设备“连接”
      • 外中断:由外部设备发生的事件引起的中断
      • 外中断处理过程
    • PC机键盘的处理过程
      • PC机键盘的处理过程
      • 键盘上键的扫描码(通码)
      • PC机键盘的处理过程——引发中断
      • PC机键盘的处理过程——执行中断例程
      • 输入 'a' 的处理过程
    • 定制键盘输入处理
      • PC机键盘的处理过程(int 9 中断例程)
      • 实现:依次显示'a'~'z'(v0.2)
      • 实现:依次显示”a”~”z”(v0.4)
      • 按下 Esc 键后改变显示的颜色
      • 实现: 按下 Esc 键后改变显示的颜色(v1.0)
    • 改写中断例程的方法
      • 改写中断例程-以int 9为例
      • 实现方法
    • 用中断响应外设
      • 如何操作外部设备?
      • 对键盘输入的处理的int 9h中断和int 16h中断
        • 演示:输入A、B、C、D、E、Shift_A、A 引发的(int 9)“动作”
        • 演示int 16h
      • 调用int 16h 从键盘缓冲区中读取键盘的输入
      • 应用示例:更改屏幕颜色
    • 应用:字符串的输入
      • 要解决的问题
      • 程序的处理过程
      • 子程序:字符栈的入栈、出栈和显示
      • 实现字符栈的入栈、出栈和显示
    • 读写磁盘
      • 如何操作磁盘?
      • BIOS提供的磁盘直接服务——int 13h
      • 用BIOS int 13h对磁盘进行读操作
      • 用BIOS int 13h对磁盘进行写操作
      • DOS中断对磁盘文件的支持——int 21H
    • 让计算机“唱歌”
      • 外部设备与如何被控制的?
      • 与"计算机唱歌"有关的硬件及控制
      • “翻译”乐谱
      • 演奏程序


    本系列文章参考汇编语言第四版和汇编语言程序设计 贺利坚主讲整理而成


    移位指令

    在这里插入图片描述


    示例:逻辑移位指令shl和shr

    在这里插入图片描述


    操作显存数据

    显示的原理

    在这里插入图片描述


    显示缓冲区的结构

    在这里插入图片描述


    显示信息的一种“直接”方式

    在这里插入图片描述


    描述内存单元的标号

    关于标号

    在这里插入图片描述
    上面的写法需要用offset来指明代码段中数据的地址


    去了冒号的数据标号

    在这里插入图片描述
    a[si]---->[si+a]


    数据标号同时描述内存地址和单元长度

    在这里插入图片描述
    mov al,b报错是因为b操作的内存单元是字大小,而al是字节大小,不符合


    更常见的方式:数据段中的数据标号

    上面都是将数据放在了代码段中,但是一般都是各段分隔开来存放。

    在这里插入图片描述
    如果将数据标号当做数据来定义,那么对应保存的是这个数据标号指向的内存地址

    a db 123
    b dw 0
    #c标号指向内存单元,保存了两个字数据,一个是a标号指向的内存偏移地址,另一个是b标号指向的内存偏移地址
    #此时c可以看做是指针的指针
    c dw a,b
    
    • 1
    • 2
    • 3
    • 4
    • 5
    a db 123
    c dw 0
    #c表示指向内存单元,保存了两个双字数据,对于每个双字数据而言,前一个保存了对应偏移地址,后一个保存了对应段地址
    c dd a,b
    
    • 1
    • 2
    • 3
    • 4

    当我们将数据标号作为数据定义的时候,是不是特别类似C语言中的指针的指针


    数据的直接定址表

    直接定址表:用查表的方法解决问题

    在这里插入图片描述


    最简解决方案

    在这里插入图片描述

    00101011 是作为低字节存放在al中的,其中前后四位各组成0-15中一个数字,然后去字符表中定位对应的位置的字符
    
    • 1
    • 因为最小操作单位是字节,所以将ah保存al的高四位,通过右移四位完成,而al保存低四位,通过一个与运算完成

    直接定址表

    在这里插入图片描述


    应用示例:为加快运算速度而采用查表方法

    在这里插入图片描述


    解决方案

    在这里插入图片描述

    • 首先使用一张表记录每个角度对应的sin值,上面使用了数据标号的方式,相当于 table dw ag0…中ag0存放的是sin0对应值的偏移地址(指针指向指针)
    • 预备动作: 将将会使用到的寄存器状态入栈,然后es附加段寄存器的段地址指向显存空间
    • al存放角度,bl存放除数30,然后进行除法运行,由于是8位除法,因此商会被保存在al中,余数被保存在ah中,这里我们只关心商
    • 将商保存到bl中,bh置空,此时bl中存放的就是偏移地址,但是单位是字节
    • bx需要变为两倍,因为上面table表的单位是字,而这里是字节
    • 从table表中根据偏移地址,取得对应字符串的偏移地址,因为这里是数据标号指向数据标号,可以看做是指针指向指针,指针的值就是他执行的内存地址
    • 通过bx中保存的字符串偏移地址,定位到对应的内存地址,然后挨个字节依次输出,直到遇到0为止
    • 恢复相关寄存器的状态

    代码的直接定址表

    使用代码的直接定址表解决问题

    在这里插入图片描述


    各种功能的实现

    在这里插入图片描述
    在这里插入图片描述
    这里重点关注的不在是各个功能的具体实现了,而是主程序中通过查表得到每个子程序开始的地址,这个操作是如何完成的

    • 通过在ah中设置需要执行的子程序在表中的相对偏移地址,但是ah保存的偏移地址单位是字节,而表单位是字,因此还需要*2,得到子程序在表中真实的偏移地址

    直接写址表的优势

    在这里插入图片描述
    查表可以提高速度,并且可以使程序架构非常清晰易懂,也便于程序扩充。

    查表的思想与策略模式类似,都是用来解决一堆IF...ELSE判断的


    中断及其处理

    中断的概念

    在这里插入图片描述


    8086的内中断

    在这里插入图片描述


    中断处理程序

    在这里插入图片描述

    • 因为8086CPU的中断向量表中,每个中断程序占据四个字节,前两个字节保存中断程序代码段的偏移地址,后两个字节保存中断程序代码段的段地址。

    并且因为每个中断程序占据四个字节,因此IP与N是有规律可循的,IP=N4,CS=N4+2

    当发生中断时,先查表得到中断程序的地址,然后设置CS和IP的值即可去执行中断程序


    案例:系统中的0号中断

    在这里插入图片描述
    当发生除法错误时,触发0号中断,此时会去查表得到0号中断程序的地址,然后设置CS和IP指向中断程序地址,然后执行中断程序


    中断过程

    在这里插入图片描述

    执行中断程序前需要先保护现场,这点很重要,主要是保存标志寄存器的状态和当前程序的地址


    编制中断处理程序

    中断处理程序及其结构

    在这里插入图片描述


    编制中断处理程序——以除法错误中断为例

    在这里插入图片描述


    do0子程序应该放在哪里?

    在这里插入图片描述


    程序框架

    在这里插入图片描述
    安装程序就是把程序代码送入到先前指定存放程序的内存空间中去,然后更改中断向量表0号表项存放的0号中断程序的地址即可。


    do0安装程序的实现

    在这里插入图片描述

    程序占用的总共字节数,可以通过两个地址标号表示地址直接差值算出来


    do0子程序的实现

    在这里插入图片描述
    显示字符,就是将对应字符写出到显示缓冲区即可,然后设置中断向量表就是将do0中断程序的入口地址,写入到中断向量表的0号表项中

    因为do0中断程序中mov ax,4c00h int 21h会直接结束程序运行,返回DOS系统,因此并不会在中断程序执行结束后,返回原有程序继续执行。


    小结

    在这里插入图片描述


    单步中断

    由Debug中的t命令说起……

    在这里插入图片描述


    单步中断过程与处理

    在这里插入图片描述


    应用:中断不响应的情况

    在这里插入图片描述
    如果在执行向ss寄存器传送数据的指令时,发生了中断,那么CPU会将相关中断寄存器值设置为0,不允许中断产生,这样下一条指令会继续执行,执行完下一条指令后,再进入中断

    因此右边的写法是错误的,因为这样写的话,mov ss,ax和mov ax,0会一起连续执行,而mov sp,10指令会单步执行


    由int指令引发的中断

    int n引起的中断

    在这里插入图片描述


    编写供应用程序调用的中断例程

    在这里插入图片描述


    示例 :中断7ch的中断例程

    在这里插入图片描述
    在执行int n中断之前,会把当前CS和IP寄存器状态入栈,还有标志寄存器状态入栈,然后中断例程执行结束后,再将相关状态出栈,进行现场还原。

    在这里插入图片描述
    如果中断程序中使用到了相关寄存器,也需要在使用前保存对应寄存器状态,程序结束后恢复


    BIOS和DOS中断处理

    BIOS——基本输入输出系统

    在这里插入图片描述


    BIOS中断调用示例

    在这里插入图片描述


    有哪些BIOS中断,怎么用?

    在这里插入图片描述


    汇编的强大功能,还有DOS中断!

    在这里插入图片描述


    int 21HDOS 中断例程的应用

    在这里插入图片描述


    BIOS和DOS中断例程的安装过程

    在这里插入图片描述


    端口的读写

    用端口访问外设:以发声为例

    在这里插入图片描述


    CPU的邻居

    在这里插入图片描述
    CPU通过这些端口控制各种芯片的行为,这些端口实质就是寄存器,但是是与对应芯片相关的寄存器,不是cpu内部从寄存器,这些芯片通过读取这些寄存器的值,知道自己应该干什么


    端口的读写

    在这里插入图片描述


    端口的读写过程演示

    in al, 20h 
    out 21h, al
    
    • 1
    • 2

    在这里插入图片描述

    在这里插入图片描述


    I/O端口分配

    在这里插入图片描述


    端口的读写指令示例

    在这里插入图片描述


    操作CMOS RAM芯片

    CMOS RAM 芯片

    在这里插入图片描述


    端口操作示例:提取CMOS RAM中存储的时间信息

    在这里插入图片描述


    在屏幕中间显示当前的月份

    在这里插入图片描述


    外设连接与中断

    CPU通过端口与外部设备“连接”

    在这里插入图片描述


    外中断:由外部设备发生的事件引起的中断

    在这里插入图片描述


    外中断处理过程

    在这里插入图片描述


    PC机键盘的处理过程

    PC机键盘的处理过程

    在这里插入图片描述


    键盘上键的扫描码(通码)

    在这里插入图片描述


    PC机键盘的处理过程——引发中断

    在这里插入图片描述

    控制键和切换键由键盘状态字节负责存储,该字节每一位都代表一个按键的状态


    PC机键盘的处理过程——执行中断例程

    在这里插入图片描述


    输入 ‘a’ 的处理过程

    在这里插入图片描述
    在这里插入图片描述


    定制键盘输入处理

    PC机键盘的处理过程(int 9 中断例程)

    在这里插入图片描述


    实现:依次显示’a’~‘z’(v0.2)

    在这里插入图片描述

    空循环的设计给出一个思路:dx和ax都赋值一个最大值,然后先把ax寄存器的值减到0结束,结束后再把dx的值也减到0


    实现:依次显示”a”~”z”(v0.4)

    在这里插入图片描述


    按下 Esc 键后改变显示的颜色

    在这里插入图片描述


    实现: 按下 Esc 键后改变显示的颜色(v1.0)

    在这里插入图片描述
    在轮询显示a–z的过程中,按下任何键,如果触发了中断,首先会去调用其原本的中断例程,原本的中断例程执行结束后,如果按下的是ESC键还会去额外改变当前显示字体的颜色,如果是其他键,就没有额外的功能了


    改写中断例程的方法

    改写中断例程-以int 9为例

    在这里插入图片描述


    实现方法

    在这里插入图片描述

    • 安装新程序是先计算出int9和int9end数据标号之间的字节差值,即等于程序的大小,然后循环拷贝所有字节到0:204h处
    • 将原先中断地址保存到2:200单元处
    • 将int9中断调用的中断例程变为我们新写的中断例程地址,即0:204h,并且这个过程要保证不被可屏蔽中断打断,通过cli设置完成,结束后,再允许被打断,通过STI完成
    • 程序返回

    用中断响应外设

    如何操作外部设备?

    在这里插入图片描述


    对键盘输入的处理的int 9h中断和int 16h中断

    在这里插入图片描述


    演示:输入A、B、C、D、E、Shift_A、A 引发的(int 9)“动作”

    在这里插入图片描述
    在这里插入图片描述
    上面是输入完ABCDE后的,键盘输入缓冲区的状态,下面输入SHIFT_A

    在这里插入图片描述
    此时我们再按下一个A

    在这里插入图片描述

    Shift标志为还原


    演示int 16h

    用int 16h读取出 用int 9h存入缓 冲区的数据

    键盘缓冲区的实现

    • 共16字
    • 用环形队列
    • 可存储15个按 键扫描码

    在这里插入图片描述
    依次从键盘缓冲区读取出一个字,放入数据缓冲寄存器,然后再放入AX中,AH存放扫描码,AL存放ASCII


    调用int 16h 从键盘缓冲区中读取键盘的输入

    在这里插入图片描述


    应用示例:更改屏幕颜色

    在这里插入图片描述


    应用:字符串的输入

    要解决的问题

    在这里插入图片描述


    程序的处理过程

    在这里插入图片描述


    子程序:字符栈的入栈、出栈和显示

    在这里插入图片描述


    实现字符栈的入栈、出栈和显示

    在这里插入图片描述
    当一个程序中存在若干子功能的时候,一般不采用挨个判断方式,而采用查表法来决定当前应该调用哪一个子功能


    读写磁盘

    如何操作磁盘?

    在这里插入图片描述


    BIOS提供的磁盘直接服务——int 13h

    在这里插入图片描述


    用BIOS int 13h对磁盘进行读操作

    在这里插入图片描述


    用BIOS int 13h对磁盘进行写操作

    在这里插入图片描述


    DOS中断对磁盘文件的支持——int 21H

    在这里插入图片描述


    让计算机“唱歌”

    外部设备与如何被控制的?

    在这里插入图片描述
    程序可以直接访问外设,是通过端口的形式进行访问的


    与"计算机唱歌"有关的硬件及控制

    在这里插入图片描述
    让计算机唱歌,需要与8253和8255芯片打交道,而CPU想要控制这两个芯片,需要通过对应两个芯片提供的端口进行操控

    因为进行了统一编址,所以我们可以很容易定位到这两个端口的地址都是什么,然后通过in和out指令写入数据操作它,获取从对应的端口读取出我们需要的数据。


    “翻译”乐谱

    在这里插入图片描述


    演奏程序

    在这里插入图片描述


  • 相关阅读:
    Learning Dynamic Memory Networks for ObjectTracking(论文翻译)
    text2
    什么是TypeScript
    flask框架+pygal+sqlit3搭建图形化业务数据分析平台
    多线程设计模式【多线程上下文设计模式、Guarded Suspension 设计模式、 Latch 设计模式】(二)-全面详解(学习总结---从入门到深化)
    【毕业设计】基于单片机的心率血氧健康监测手表 - 物联网 嵌入式
    03. Python中的语句
    【FI】FB02中Coding Block字段如何设置为可修改
    前后端分离——瑞吉外卖
    OpenGL - Gamma Correction
  • 原文地址:https://blog.csdn.net/m0_53157173/article/details/125374505
  • 最新文章
  • 攻防演习之三天拿下官网站群
    数据安全治理学习——前期安全规划和安全管理体系建设
    企业安全 | 企业内一次钓鱼演练准备过程
    内网渗透测试 | Kerberos协议及其部分攻击手法
    0day的产生 | 不懂代码的"代码审计"
    安装scrcpy-client模块av模块异常,环境问题解决方案
    leetcode hot100【LeetCode 279. 完全平方数】java实现
    OpenWrt下安装Mosquitto
    AnatoMask论文汇总
    【AI日记】24.11.01 LangChain、openai api和github copilot
  • 热门文章
  • 十款代码表白小特效 一个比一个浪漫 赶紧收藏起来吧!!!
    奉劝各位学弟学妹们,该打造你的技术影响力了!
    五年了,我在 CSDN 的两个一百万。
    Java俄罗斯方块,老程序员花了一个周末,连接中学年代!
    面试官都震惊,你这网络基础可以啊!
    你真的会用百度吗?我不信 — 那些不为人知的搜索引擎语法
    心情不好的时候,用 Python 画棵樱花树送给自己吧
    通宵一晚做出来的一款类似CS的第一人称射击游戏Demo!原来做游戏也不是很难,连憨憨学妹都学会了!
    13 万字 C 语言从入门到精通保姆级教程2021 年版
    10行代码集2000张美女图,Python爬虫120例,再上征途
Copyright © 2022 侵权请联系2656653265@qq.com    京ICP备2022015340号-1
正则表达式工具 cron表达式工具 密码生成工具

京公网安备 11010502049817号