汇编 端口

端口

前面讲过,各种存储器都和CPU的地址线、数据线、控制线相连。CPU在操控它们的时候,把它们都当作内存来对待,把它们总的看做一个由若干存储单元组成的逻辑存储器,这个逻辑器我们称其为内存地址空间。

在PC机系统中,和CPU通过总线相连的芯片除各种存储器外,还有以下3种芯片:

1)各种接口卡(比如:网卡、显卡)上的接口芯片,它们控制接口卡进行工作;

2)主板上的接口芯片,CPU通过它们对部分外设进行访问;

3)其他芯片,用来存储相关的系统信息,或进行相关的输入输出处理。

在这些芯片中,都有一组可以由CPU读写的寄存器。这些寄存器,它们在物理上可能处于不同的芯片中,但是它们在以下两点上相同:

1)都和CPU的总线相连,当然这种连接是通过它们所在的芯片进行的;

2)CPU对它们进行读或写的时候都通过控制线向它们所在的芯片发出端口读写命令。

可见,从CPU的角度,将这些寄存器都当作端口,对它们进行统一编址,从而建立了一个统一的端口地址空间。每一个端口在地址空间中都有一个地址。

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

1)CPU内部的寄存器;

2)内存单元;

3)端口中。(芯片中的寄存器)

端口的读写

在访问端口的时候,CPU通过端口地址来定位端口。因为端口所在的芯片和CPU通过总路线相连,所以,端口地址和内存地址一样,通过地址总路线来传送。在PC系统中,CPU最多可以定位64K个不同的端口。则端口地址的范围为0~65535。

对端口的读写不能用mov,push,pop等内存读写指令。

端口的读写指令只有两条:in和out,分别用于从端口读出数据和往端口写入数据。

我们来看一下CPU执行内存访问指令和端口访问指令时候,总线上的信息:

1)访问内存:

mov ax,ds:[8]               ;假设执行前(ds)=0

执行时与总路线相关的操作:

(1)CPU通过地址线将地址信息8发出;

(2)CPU通过控制线发出内存读命令,选中存储器芯片,并通知它,将要从中读取数据;

(3)存储器将8号单元中的数据通过数据线送入CPU。

2)访问端口:

in al,60h         ;从60h号端口读入一个字节

执行时与总路线相关的操作:

(1)CPU通过地址线将地址信息60h发出;

(2)CPU通过控制线发出端口读命令,选中端口所在的芯片,并通知它,将要从中读取数据;

(3)端口所在的芯片将60h端口中的数据通过数据线送入CPU。

在in和out指令中,只能使用ax或al来存放从端口中读入的数据或要发送到端口中的数据。访问8位端口时用al,访问16位端口时用ax。

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

in al,20h         ;从20h端口读入一个字节

out 20h,al              ;往20h端口写入一个字节

对256~65535的端口进行读写时,端口号放在dx中:

mov dx,3f8h          ;将端口号3f8h送入dx

in al,dx                  ;从3f8h端口读入一个字节

out dx,al                ;向3f8h端口写入一个字节

CMOS RAM芯片

我们通过对CMOS RAM的读写来体会一下对端口的访问。

PC机中,有一个CMOS RAM芯片,一般简称为CMOS。此芯片的特征如下:

1)包含一个实时钟和一个有128个存储单元的RAM存储器(早期的计算机为64个字节)。

2)该芯片靠电池供电。所以,关机后其内部的实时钟仍可正常工作,RAM中的信息不丢失。

3)128个字节的RAM中,内部实时钟占用0~0dh单元来保存时间信息,其余大部分单元用来保存系统配置信息,供系统启动时BIOS程序读取。BIOS也提供了相关的程序,使我们可以在开机的时候配置CMOS RAM中的系统信息。

4)该芯片内部有两个端口,端口地址为70h和71h。CPU通过这两个端口来读写CMOS RAM。

5)70h为地址端口,存放要访问的CMOS RAM单元的地址:71h为数据端口,存放从选定的CMOS RAM单元中读取的数据。可见,CPU对CMOS RAM的读写分两步进行了,比如:读CMOS RAM的2号单元:

(1)将2送入端口70h;

(2)从71h读出2号单元的内容。

检测点14.1

1)编程:读取CMOS RAM的2号单元的内容。

mov al,2h

out 70h,al              ;把2写入地址端口。

in 71h,al         ;把数据端口的内容读出放入al寄存器。

2)编程:向CMOS RAM的2号单元写入0。

mov al,2h

out 70h,al              ;把2写入地址端口

mov al,0

out 71h,al              ;把0写入数据端口

shl和shr指令

shl和shr是逻辑移位指令。

shl是逻辑左移指令,它的功能为:

1)将一个寄存器或内存单元中的数据向左移位;

2)将最后移出的一位写入CF中;

3)最低位用0补充。

指令:

mov al,01001000b

shl al,1                  ;将al中的数据左移一位

执行后(al)=10010000b,CF=0。

如果移动位数大于1时,必须将移动位数放在cl中。

比如,指令:

mov al,01010001b

mov cl,3

shl al,cl

执行后(al)=10001000b,因为最后移出的一位是1,所以CF=1。

可以看出,将X逻辑左移一位,相当于执行X=X*2。

shr是逻辑右移指令,它和shl所进行的操作刚好相反:

1)将一个寄存器或内存单元中的数据向右移位;

2)将最后移出的一位写入CF中。

3)最高位用0补充。

指令:

mov al,10000001b

shr al,1                  ;将al中的数据右移一位

执行后(al)=01000000b,CF=1

如果移动位数大于1时,必须将移动位数放在cl中。

比如,指令:

mov al,01010001b

mov cl,3

shr al,cl

执行后(al)=00001010b,因为最后移出的一位是0,所以CF=0。

可以看出将X逻辑右移一位,相当于执行X=X/2。

检测点14.2

编程:用加法和移位指令计算(ax)=(ax)*10

提示:(ax)*10 = (ax)*2 + (ax)*8

assume cs:code

code segment

start:    mov ax,1000h

mov bx,ax

shl bx,1          ;(ax)=(ax)*2

mov cl,3

shl ax,cl         ;(ax)=(ax)*8

add ax,bx              ;(ax)=(ax)*10

code ends

end start

CMOS RAM中存储的时间信息

在CMOS RAM中,存放着当前的时间:年、月、日、时、分、秒。这6个信息的长度都为1个字节,存放单元为:

秒:0     分:2     时:4     日:7     月:8     年:9

这些数据以BCD码的方式存放。

BCD码是以4位二进制数表示十进制数码的编码方法,如下表示:

十进制

0

1

2

3

4

5

6

7

8

9

BCD码

0000

0001

0010

0011

0100

0101

0110

0111

1000

1001

比如:数值26,用BCD码表示为:0010 0110 (2 6)

可见,一个字节可表示两个BCD码。则CMOS RAM存储时间信息的单元中,存储了用两个BCD码表示的两位十进制数,高4位的BCD码表示十位,低4位的BCD码表示个位。比如:00010100b表示14。

编程:在屏幕中间显示当前的月份。

分析:这个程序主要做两部分工作:

(1)从CMOS RAM的8号单元读出当前月份的BCD码:

mov al,8         ;首先要向地址端口70h

out 70h,al              ;写入要访问的单元的地址。

in al,71h         ;然后,从数据端口71h中取得指定单元中的数据。

(2)将用BCD码表示的月份以十进制的形式显示到屏幕上。

BCD码值=十进制数码值,则BCD码值+30h=十进制数对应的ASCII码。

从CMOS RAM的8号单元读出的一个字节中,包含了两个BCD码表示的两位十进制数,高4位的BCD码表示十位,低4位的BCD码表示个位。比如:00010100表示14。

我们需要进行两步工作:

1)将从CMOS RAM的8号单元中读出的一个字节,分为两个表示BCD码值的数据。

mov ah,al              ;al中为从CMOS RAM的8号单元读出的数据

mov cl,4

shr ah,cl         ;ah中为月份的十位数码值

and al,00001111b    ;al中为月份的个位数码值

2)显示(ah)+30h和(al)+30h对应的ASCII码字符。

完整程序如下:

assume cs:code

code segment

start:

mov al,8

out 70h,al

in al,71h   ;从CMOS RAM的8号单元读出当前月份的BCD码。

mov ah,al   ;ah,al都存储着当前月份的BCD码。

mov cl,4

shr ah,cl   ;ah中内容逻辑右移4位,则只剩下月份的十位数码。

and al,00001111b ;al中内容将只剩下月份的个位数码。

add ah,30h

add al,30h ;得到十进制数码的ASCII码值。

mov bx,0b800h

mov es,bx

mov byte ptr es:[160*12+40*2],ah ;显示月份的十位数码

mov byte ptr es:[160*12+40*2+2],al ;显示月份的个位数码

mov ax,4c00h

int 21h

code ends

end start

汇编CMOS的更多相关文章

  1. 汇编实验14:访问CMOS RAM

    汇编实验14:访问CMOS RAM 任务 编程,以“年/月/日 时:分:秒”的格式,显示当前的日期,时间. 预备知识 CMOS存储当前时间的信息:年.月.日.时.分.秒.这六个信息的长度均为1个字节, ...

  2. 汇编试验十四:访问CMOS RAM

    CMOS RAM 芯片的特征: 包含一个时钟和一个有128个存储单元的RAM存储器. 该芯片靠电池供电.所以,关机后其内部的时钟仍可正常工作,RAM中的信息不丢失. 128个字节的RAM中,内部时钟占 ...

  3. ATT 汇编语法

      在研华的pc104上使用看门狗要使用汇编.使用汇编来修改CMOS里面的参数.也就是内联汇编.linux下gcc只支持ATT汇编.所以这儿有必要将ATT语法学习学习.以后需要的时候翻出来温习温习. ...

  4. CMOS and BIOS

    1,cmos简介.   cmos是主板上一块可读写的RAM芯片.用途:主要用来保存当前系统的硬件配置和操作人员对某些参数的设定.cmos芯片是由一块纽扣电池供电.因此在关机状态内部信息也不会丢失. 2 ...

  5. 汇编学习笔记(11)int指令和端口

    格式 int指令也是一种内中断指令,int指令的格式为int n,n是中断类型码.也就是说,使用int指令可以调用任意的中断例程,例如我们可以显示的调用0号中断例程,还记得在汇编学习笔记(10)中我们 ...

  6. 汇编入门学习笔记 (十二)—— int指令、port

    疯狂的暑假学习之  汇编入门学习笔记 (十二)--  int指令.port 參考: <汇编语言> 王爽 第13.14章 一.int指令 1. int指令引发的中断 int n指令,相当于引 ...

  7. u-boot源码汇编段简要分析

    Hi,大家好!我是CrazyCatJack,你们可以叫我CCJ或者疯猫.今天我给大家带来的是u-boot的源代码汇编段分析,以后还会给大家讲解后续的C代码,请持续关注哦^_^ 先简单说一下u-boot ...

  8. GCC 预处理、编译、汇编、链接..

    1简介 GCC 的意思也只是 GNU C Compiler 而已.经过了这么多年的发展,GCC 已经不仅仅能支持 C 语言:它现在还支持 Ada 语言.C++ 语言.Java 语言.Objective ...

  9. GDB调试汇编堆栈过程分析

    GDB调试汇编堆栈过程分析 分析过程 这是我的C源文件:click here 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb ...

随机推荐

  1. IE6下png背景不透明——张鑫旭博客读书笔记

    从今天开始跟着大牛张鑫旭的步伐,每天进步一点点 问题:IE6不支持png背景透明或半透明 一.可解决的方法 补充:css滤镜主要是用来实现图像的各种特殊效果.(了解) css滤镜的标识符是“filte ...

  2. SQL注入中的整型注入实验

    首先搭建一个用于注入的环境 目录结构 conn.php 用来连接数据库的文件PHP文件 index.php 用来执行SQL命令,以及返回查询结构 index.html              一个存 ...

  3. 【排序】插入排序:最稳定:时间复杂度O(n^2)

    想象着自己在玩扑克的时候抓牌,每抓到一张牌,按照从小到大的顺序排序. 如果第二张的点数小于第一张,就交换这两张牌,默认每次抓牌之前,前面的已经排好序了. 再来一张牌,与第二张比较,如果小于第二张,交换 ...

  4. MySQL从服务配置文件

    [mysql]port=3306socket=/var/lib/mysql/mysql.sockdefault-character-set = utf8mb4 [mysqld]server-id=2l ...

  5. iOS图片目录批量复制到android图片目录

    复制shell脚本 #!/bin/bash for i in `ls` do for imgname in `ls $i | grep '^WM.*'` do echo $imgname cp $i/ ...

  6. OpenGL列主元矩阵和列主序存储

    OpenGL矩阵要考虑两个点,一个是向量如何排布,一个是矩阵如何存储和恢复. 1.排布 排布决定了运算的顺序.OpenGL使用的是列主元,它的意思就是一个4X4的矩阵是由4个列向量构成(这里的v1,v ...

  7. Thread源码分析-java8

    1.Thread特性分析 守护线程Daemon 定性:支持性线程,主要用于程序中后台调度以及支持性工作. 当JVM中不存在Daemon线程时,JVM将会退出. 将一个线程设定为Daemon的方法: 调 ...

  8. JavaScript中数据类型和typeof返回的数据类型

    除了上图,要注意三点:1.symbol是ES6中新增的数据类型 2.typeof(null)结果是Object 3.typeof(Object)和typeof(Array)的结果是function,因 ...

  9. nodeJS进程管理器pm2

    pm2是一个带有负载均衡功能的Node应用的进程管理器.当你要把你的独立代码利用全部的服务器上的所有CPU,并保证进程永远都活着,0秒的重载, PM2是完美的. PM2是开源的基于Nodejs的进程管 ...

  10. Bootstrap历练实例:表单控件状态(禁用的字段集fieldset)

    禁用的字段集 fieldset 对 <fieldset> 添加 disabled 属性来禁用 <fieldset> 内的所有控件. <!DOCTYPE html>& ...