汇编学习--第十六天

第十四章 端口

CPU可以直接读写数据的地方:

  1. CPU内部的寄存器
  2. 内存单元
  3. 端口

14.1 端口的读写

对8位端口进行读写,用al保存数据,对16位端口进行读写,用ax保存数据

对0~255以内端口进行读写时

in al,20h
out 20h,al

对256~65535端口进行读写时,需要用dx保存端口号

mov dx,3f8h
in al,dx
out dx,al

14.2 CMOS RAM

70h地址端口:存放要访问的CMOS RAM单元的地址

71h数据端口:存放从选定的CMOS EAM单元中读取数据

(1)

assume cs:code
code segment
start:
    mov al,2
    out 70h,al
    in al,71h
    
    mov ax,4c00h
    int 21h
code ends
end start

(2)

assume cs:code
code segment
start:
    mov al,2
    out 70h,al
    mov al,0
    out 71h,al
    
    mov ax,4c00h
    int 21h
code ends
end start

14.3 shl和shr指令

shl逻辑左移指令

shr逻辑右移指令

功能:

  1. 将一个寄存器或内存单元中的数据左/右移位
  2. 将最后移出的一位写入CF中
  3. 最低位/最高位用0补存

如果要移动一位以上,需要用cl寄存器保存次数

检测点 14.2

assume cs:code
code segment
start:
    mov ax,66
    mov bx,ax
    shl ax,1
    mov cl,3
    shl bx,cl
    add ax,bx
    
    mov ax,4c00h
    int 21h
code ends
end start

14.4 CMOS RAM中储存的时间信息

存放的当前时间包括:年,月,日,时,分,秒,长度都为1字节,存放单元在

秒:0  分:2  时:4

日:7  月:8  年:9

实验14 访问CMOS RAM

assume cs:code
data segment
    db 9,8,7,4,2,0
data ends
code segment
start:
    mov ax,data
    mov ds,ax
    mov bx,0b800h
    mov es,bx
    mov di,160*12+33*2
    mov si,0
    mov cx,6
    
s:
    call show
    
    cmp byte ptr ds:[si],7
    jna s1;不大于7就跳转
    ;年,月
    mov byte ptr es:[di],'/'
    jmp stop
s1:
    jb s2;小于7就跳转
    ;日
    mov byte ptr es:[di],' '
    jmp stop
s2:
    cmp byte ptr ds:[si],0
    je stop;等于0就跳转
    ;时,分
    mov byte ptr es:[di],':'
    
stop:
    inc si
    add di,2
    loop s
    mov ax,4c00h
    int 21h
    
show:
    push cx
    mov al,ds:[si]
    out 70h,al
    in al,71h
    
    ;获取数据
    mov ah,al
    mov cl,4
    shr ah,cl
    and al,00001111b
    
    ;十进制转ASCII码
    add ah,30h
    add al,30h
    
    ;写入显示缓冲区
    mov es:[di],ah
    mov byte ptr es:[di+2],al
    add di,4
    pop cx
    ret
    
code ends
end start

第15章 外中断

 15.1 接口芯片和端口

外设的输入不直接送入内存和CPU,而是先送入端口中;CPU向外设的输出也不是直接输入外设,而是先送入端口中,再由相关的芯片送到外设,CPU还可以向外设输出控制信息,而这些控制命令也是先送到相关芯片的端口中,然后再由相关的芯片根据命令对外设实施控制。

可见,CPU通过端口和外部设备进行联系。

15.2 外中断信息

外中断源分为:

  • 可屏蔽中断:CPU可以不响应的外中断。sti,设置IF=1;cli,设置IF=0
  • 不可屏蔽中断:CPU必须响应的外中断。中断类型码固定为2

15.3 PC机键盘的处理过程

1.键盘输入

一般按下一个键时产生的扫描码称为通码,松开一个键产生的扫描码称为断码,扫描码长度为一个字节,通码第7位为0,断码第7位为1,即:断码=通码+80h

2.引发9号中断

键盘的输入到达60h端口时,相关的芯片就会向CPU发出中断类型码为9的可屏蔽中断信息。CPU检测到该信息后,如果IF=1,则响应中断,否则就会屏蔽中断。

3.执行int9中断例程

BIOS键盘缓冲区 它是系统启动后,BIOS用于存放int 9中断历程所接收的键盘输入的内存区。该内存区可以存储15个键盘输入,因为int 9中断例程除了接收扫描码外,还要产生对应的ASCII码,所以,在缓冲区中,一个键盘输入用一个字单元存放,高位扫描码,低位字符码。

inc和dec影响除CF位以外的标志寄存器

15.4 编写int9中断例程

模拟以下几步:

  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]

注意:

  1. 该程序要在返回之前,将中断向量表中的int 9中断例程的入口地址恢复为原来的地址,否则程序返回后,别的程序将无法使用键盘。
  2. 取中断码是为了确定程序入口地址,在这里中断码已经确定,所以不能用int指令调用。
assume cs:code
stack segment
    db 128 dup (0)
stack ends
data segment
    dw 0,0
data ends
code segment
start:
    ;栈段地址
    mov ax,stack
    mov ss,ax
    mov sp,128
    
    ;数据段地址
    mov ax,data
    mov ds,ax
    
    ;原9号中断向量表中的入口地址保存到ds:[0],ds:[2]
    mov ax,0
    mov es,ax
    push es:[9*4]
    pop ds:[0]
    push es:[9*4+2]
    pop ds:[2]
    
    ;设置新int9中断例程入口地址
    mov word ptr es:[9*4],offset int9
    mov es:[9*4+2],cs
    
    ;设置显示缓冲区
    mov ax,0b800h
    mov es,ax
    mov di,160*12+40*2
    mov ah,'a'
s:
    ;显示字符
    mov es:[di],ah
    call delay
    inc ah
    cmp ah,'z'
    jna s
    
    ;恢复原来int9中断例程入口地址
    mov ax,0
    mov es,ax
    push ds:[0]
    pop es:[9*4]
    push ds:[2]
    pop es:[9*4+2]
    
    mov ax,4c00h
    int 21h

    ;延时
delay:
    push dx
    push ax
    ;10 0000h写入高地址和低地址
    mov dx,10h
    mov ax,0
s1:
    ;只能使用sub,不能dec
    sub ax,1
    sbb dx,0
    cmp dx,0
    jne s1
    cmp ax,0
    jne s1
    
    pop ax
    pop dx
    ret
    
    ;新中断例程
int9:
    push ax
    push bx
    push es
    ;从60h端口读出键盘的输入
    in al,60h
    
    pushf
    pushf
    ;取出标志寄存器
    pop bx
    ;IF=0,TF=0
    and bh,11111100b
    ;保存标志寄存器
    push bx
    popf
    
    call dword ptr ds:[0];对int指令进行模拟,调用原来的int9中断例程,处理其他硬件细节

    cmp al,1;判断是否按下ESC
    jne int9ret
    
    mov ax,0b800h
    mov es,ax
    inc byte ptr es:[di+1];属性值+1
int9ret:
    pop es
    pop bx
    pop ax
    iret
    
code ends
end start

猜你喜欢

转载自www.cnblogs.com/Mayfly-nymph/p/11228966.html