汇编学习--第十六天
Posted mayfly-nymph
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编学习--第十六天相关的知识,希望对你有一定的参考价值。
第十四章 端口
CPU可以直接读写数据的地方:
- CPU内部的寄存器
- 内存单元
- 端口
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逻辑右移指令
功能:
- 将一个寄存器或内存单元中的数据左/右移位
- 将最后移出的一位写入CF中
- 最低位/最高位用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中断例程
模拟以下几步:
- 标志寄存器入栈;
- IF=0,TF=0;
- CS,IP入栈
- (IP)=(DS)*16+0;(CS)=(DS)*16+2
3,4可以简化为call dword ptr ds:[0]
注意:
- 该程序要在返回之前,将中断向量表中的int 9中断例程的入口地址恢复为原来的地址,否则程序返回后,别的程序将无法使用键盘。
- 取中断码是为了确定程序入口地址,在这里中断码已经确定,所以不能用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
以上是关于汇编学习--第十六天的主要内容,如果未能解决你的问题,请参考以下文章
《Python编程从入门到实践》——学习python的第十六天
《Python编程从入门到实践》——学习python的第十六天