王爽 《汇编语言》 读书笔记 十四 端口

来源:互联网 发布:ubuntu下的下载工具 编辑:程序博客网 时间:2024/05/14 20:58

第十四章 端口

cpu中通过总线连接的设备除了各种存储器以外还有以下3种芯片。

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

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

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


这些芯片中的,都有一组可以由cpu读写的寄存器。

1)都和cpu的总线相连(通过其所在的芯片)

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


将这些寄存器都当作端口,对其进行统一的编址,从而建立了一个统一的端口地址空间。

cpu可以直接读写一下3个地方的数据

1)cpu内部的寄存器

2)内存单元

3)端口


14.1 端口的读写

cpu通过端口地址定位端口。中pc系统中,cpu最多可以定位64KB个不同端口(0-65535)

in 和 out

并且传送数据只能用al 和ax

in al, 20h

out 20h, al


mov dx, 3f8h

int al, dx

out dx, al


14.2 CMOS RAM 芯片

PC中有一个CMOS RAM芯片,一般称为CMOS。具有如下特征

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

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

3)128字节的RAM中,内部时钟占有0-0dh单元来保存时间信息,其余大部分单元用语保存系统配置信息,供系统启动时BIOS程序读取。

4)该芯片内部有两个端口,地址70h 71h

5)70h为地址端口,存放要访问的CMOS RAM单元的地址; 71h为数据端口,存放从选定的CMOS RAM单元中读取数据,或要写入其中的数据。

a。将2 送入端口70h

b。从端口71h读取2号单元的内容


1.读取CMOS RAM的2号单元的内容

; read data from #2 of CMOS RAMassume cs:codecode segmentstart:mov al, 2out 70h, al; select #ram 2 of CMOSin al, 71h; raed data from port 71hmov ax, 4c00hint 21hcode endsend start
运行结果



2. 向CMOS RAM的2号单元写入0

; write data to RAM #2 of CMOSassume cs:codecode segmentstart:mov al, 2out 70h, al; select ram #2 of CMOSmov al, 0; set data 0out 71h, al; store the data ; read data from cmos to verify the progressmov al, 2out 70h, al; select ram #2 of CMOSin al, 71h; raed data from port 71hmov ax, 4c00hint 21hcode endsend start



14.3 shl 和 shr 指令

shl

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

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

3)最低位用0补充。

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

例如  mov al, 01010001b

mov cl, 3

she al, cl ; 左移3位 CF仅根最后移出的那一位有关


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

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

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

3)最高位用0补充。

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

assume cs:codestack segmentdb 16 dup (0)stack endscode segmentstart: mov ax, stackmov ss, axmov sp, 10hmov ax, 10; init data as 10push axshl ax, 1mov bx, axpop axmov cl, 3shl ax, cladd ax, bxmov ax, 4c00hint 21hcode endsend start
运行结果


14.4 CMOS RAM中存储的时间信息

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

assume cs:codecode segmentstart:mov al, 8out 70h, al; selet RAM #8 of CMOSin al, 71h; read data from RAM#8 of CMOS; start to process the datamov ah, almov cl, 4shr ah, cl; right shift 4 and al, 00001111b;; conver to asciiadd ah, 30hadd al, 30hmov bx, 0b800hmov es, bxmov byte ptr es:[160 * 12 + 40 * 2], ahmov byte ptr es:[160 * 12 + 40 * 2 + 2], almov ax, 4c00hint 21hcode endsend start

运行结果


实验14 访问CMOS RAM

以年月日时分秒的格式显示当前的日期,时间。

assume cs:codestack segmentdb 16 dup (0)stack endscode segmentstring:db '00/00/00 00:00:00', '$'address:db 9, 8, 7, 4, 2, 0start:mov ax, stackmov ss, axmov sp, 10hmov ax, csmov ds, axmov si, offset stringmov bx, offset addressmov cx, 6next:mov al, ds:[bx]; read the RAM#call getCMOSmov ds:[si], ahmov ds:[si + 1], alinc bxadd si, 3loop next; show the string; set cursormov ah, 2mov bh, 0mov dh, 5mov dl, 12int 10h; call int21h to show stringmov ah, 9mov dx, offset stringint 21hmov ax, 4c00hint 21h; get and convert the data to ascii from CMOS RAM; in  al = RAM #; out al = low digit of ASCII char; out ah = high digit of ASCII chargetCMOS:push cxout 70h, al; selet RAM # of CMOSin al, 71h; read data from RAM# of CMOS; start to process the datamov ah, almov cl, 4shr ah, cl; right shift 4 and al, 00001111b;; conver to asciiadd ah, 30hadd al, 30hpop cxretcode endsend start

运行结果



原创粉丝点击