介绍
CPU
可以直接读写:
CPU
的寄存器- 内存单元
- 端口
端口
各种接口卡(网卡``显卡
)上的接口芯片,控制着接口卡的工作
这些芯片中都具有能被CPU
直接读写的寄存器,通过总线与CPU
相连,因此被当作端口
端口地址范围为64KB
即0~65535(0000H~FFFFH)
写入
8 位端口
out 20h,al ; 向 20h 端口写入一个字节
out 20h,ax ; 向 20h 端口写入两个字节
16 位端口
mov dx,3f8h
out dx,al ; 向 3f8h 端口写入一个字节
读取
in al,20h
out 20h,al
写入和读取只能使用
ax
和al
COMS RAM
包含一个实时钟
和128
存储单元的RAM
时间信息保存在0~d
单元
存在两个端口70h
和71h
,分别为地址端口和数据端口
读取 2 号单元数据
- 将
2
送入70h
- 从
71h
读出数据 ``` assume cs:code
code segment
start: mov al,2 out 70h,al ; 将 al 送入端口 70h in al,71h ; 从端口 71h 处读出单元内容 mov ax,4c00h int 21h
code ends
end start
<a name="jbVQV"></a>
### 读取时间
时间信息为`秒``分``时``日``月``年`,每个占一个字节<br />使用`BCD`码保存,因此一个字节可以表示两位的十进制<br />`BCD`码 + `30h` = 十进制对应的`ASCII`
assume cs:code
code segment
start: mov al,8 ; CMOS RAM 的 8 号单元 out 70h,al in al,71h
mov ah,al
mov cl,4
shr ah,cl ; 将两个BCD码右移 4 位得到十位数
and al,00001111b ; 去掉十位数得到个位数
add ah,30h ; 加上 30h 得到 ASCII 码
add al,30h
; 写入显存中
mov bx,0b800h
mov es,bx
mov byte ptr es:[160*12+40*2],ah
mov byte ptr es:[160*2+40*2+2],al
mov ax,4c00h
int 21h
code ends
end start
<a name="Mnq9p"></a>
## 逻辑左移 shl
内存单元的数据左移,最低位用`0`补齐,最后移出去的保存在`cf`中
assume cs:code
code segment start:mov al,11001000B shl al,1 ; 左移一位
mov ax,4c00h
int 21h
code ends end start
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2327383/1642752483000-b08ad514-e4b9-4dc2-ba37-2f9737612bec.png#clientId=u76955362-745d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=190&id=u6d71a90f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=537&originWidth=1691&originalType=binary&ratio=1&rotation=0&showTitle=false&size=128840&status=done&style=none&taskId=u94c7ae7f-f456-4382-b0c9-a4a2d80d919&title=&width=599.3333740234375)
<a name="OvNt7"></a>
### 移出位数大于 1
assume cs:code
code segment start:mov al,11001000B mov cl,3 shl al,cl ; 左移一位
mov ax,4c00h
int 21h
code ends end start
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2327383/1642752758262-718f2b4e-1ca2-4dd7-aa75-39370b43b37f.png#clientId=u76955362-745d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=253&id=u598f37e9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=671&originWidth=1510&originalType=binary&ratio=1&rotation=0&showTitle=false&size=144658&status=done&style=none&taskId=u6f1ac387-6e18-4dc0-b306-953e61a441a&title=&width=568.3333740234375)
<a name="DzIMI"></a>
### 计算 ax·10
assume cs:code
code segment
start: mov ax,10 ; Ah mov bx,ax shl ax,1 ; 左移 1 位 (ax)=(ax)×2 mov cl,3 shl bx,cl ; 左移 3 位 (bx)=(ax)×8 add ax,bx ; (ax)=(ax)×2+(ax)×8 ; 结果 (ax)=64h
mov ax,4c00h
int 21h
code ends
逻辑右移 shr
最高位用0
补齐,最后移出的放在cf
里