zoukankan      html  css  js  c++  java
  • 8086键盘输入实验——《x86汇编语言:从实模式到保护模式》读书笔记07

    1.BIOS中断

    我们可以为所有中断类型自定义中断处理过程,包括内部中断、硬件中断和软中断。

    BIOS中断,又称BIOS功能调用,主要是为了方便地使用最基本的硬件访问功能。通常,为了区分针对同一硬件的不同功能,使用寄存器AH来指定具体的功能编号。

    比如说,以下的指令用于从键盘读取一个按键:

    mov ah,0x00     ;0功能号对应从键盘读字符
        int 0x16        ;键盘服务, int 0x16
                        ; 中断返回时,字符的ASCII在AL中

    需要说明的是,BIOS可能会为一些简单地外围设备提供初始化代码和功能调用代码,并填写中断向量表,但是有一些BIOS中断是由外部设备接口自己建立的。

    首先,每个外部设备接口,包括各种板卡,如网卡、显卡、键盘接口电路、硬件控制器等,都有自己的只读存储器(ROM),类似于BIOS芯片,这些ROM中提供了它们自己的功能调用例程,以及本设备的初始化代码。按照规范,前两个单元的内容是0x55和0xAA,第三个单元是本ROM中的代码长度(以512字节为单位);从第四个单元开始,就是实际的ROM代码。

    其次,我们知道,从内存物理地址A0000开始,到FFFFF结束,有相当一部分空间是留给外围设备的。如果设备存在,那么它自带的ROM会映射到分配给它的地址范围内。

    在计算机启动期间,BIOS会以2KB为单位搜索内存地址C0000~E0000之间的区域。当它发现某个区域的前两个字节是0x55和0xAA时,那意味着该区域有ROM代码的存在,是有效的。接着,它对该区域做累加和检查,看结果是否和第三个单元相符。如果相符,就从第四个单元进入。这时候,处理器执行的是硬件自带的程序指令,这些指令初始化外部设备的相关寄存器和工作状态。最后,填写相关的中断向量表,使其指向自带的中断处理过程。

    2.键盘读字符并显示的实验

    (1)代码清单

    ;代码清单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,ax
          mov sp,ss_pointer
          mov ax,[data_segment]
          mov ds,ax
          
          mov cx,msg_end-message
          mov bx,message
          
     .putc:
          mov ah,0x0e
          mov al,[bx]
          int 0x10
          inc bx
          loop .putc
    
     .reps:
          mov ah,0x00
          int 0x16
          
          mov ah,0x0e
          mov bl,0x07
          int 0x10
    
          jmp .reps
    
    ;===============================================================================
    SECTION data align=16 vstart=0
    
        message       db 'Hello, friend!',0x0d,0x0a
                      db 'This simple procedure used to demonstrate '
                      db 'the BIOS interrupt.',0x0d,0x0a
                      db 'Please press the keys on the keyboard ->'
        msg_end:
                       
    ;===============================================================================
    SECTION stack align=16 vstart=0
               
                     resb 256
    ss_pointer:
     
    ;===============================================================================
    SECTION program_trail
    program_end:

    (2)使用BIOS中断向屏幕写字符

    关于代码,头部的部分和SS,DS的初始化自然不用多说,我们已经很熟悉了。

    mov cx,msg_end-message
          mov bx,message
          
     .putc:
          mov ah,0x0e
          mov al,[bx]
          int 0x10
          inc bx
          loop .putc

    首先,把重复次数传入CX,然后让BX指向要显示的信息的首地址。

    接下来,我们要利用0x10号中断的0x0e号功能。

    BIOS中断显示服务(Video Service——INT 10H)

    功能描述:在Teletype模式下显示字符,具体说就是在屏幕的光标处写一个字符,并推进光标的位置。
    入口参数:

    AH=0EH
    AL=字符
    BH=页码
    BL=前景色(图形模式);注意,仅在图形模式下,设置BL才会改变前景色;在文本模式下,这个参数不起作用(我们的实验工作在文本模式下)
    出口参数:无

    (3)使用BIOS中断从键盘读取字符

    .reps:
          mov ah,0x00
          int 0x16
          
          mov ah,0x0e
          mov bl,0x07   ;我觉得这句可以不要
          int 0x10
    
          jmp .reps

    前面已经说了,0x16号中断的0x00号子功能是从键盘读字符。

    然后,再次利用0x10号中断的0x0e号功能,把我们从键盘输入的字符显示出来。

    BIOS中断键盘服务(Keyboard Service——INT 16H)
    功能描述:从键盘读入字符
    入口参数:

    AH=00H——读键盘
    AH=10H——读扩展键盘(可根据0000:0496H单元的内容判断:扩展键盘是否有效 )
    出口参数:

    AH=键盘的扫描码
    AL=字符的ASCII码

    (4)实验结果截图

    keyboard

    上图就是启动Bochs后,再按C之后的画面。接下来,我们就可以尝试按键,看看会发生什么眨眼

    下一次,我们就开始探索32位的x86了,你是否很期待呢?大笑

  • 相关阅读:
    记录PHP的执行时间
    Mysql数据字典导出
    PHP用post来进行Soap请求
    laravel(lumen)配置读写分离后,强制读主(写)库数据库,解决主从延迟问题
    使用vagrant构建你们团队的开发环境
    Lumen框架使用Redis与框架Cache压测比较
    使用php-cs-fixer格式化你的代码
    Javascript下拉导航
    jsf2.0视频
    jsf2入门视频 教程
  • 原文地址:https://www.cnblogs.com/longintchar/p/5224408.html
Copyright © 2011-2022 走看看