输入输出指令用来完成I/O端口与累加器之间的数据传送,指令中给出I/O端口的地址值。当执行输入指令时,把指定端口中的数据读入累加器中;当执行输出指令时,则把累加器中的数据写入指定的端口中。
IN输入指令
指令格式:
IN AL, 端口地址
或
IN AX, 端口地址
端口地址存放在DX寄存器中
IN AL, DX
或
IN AX, DX
- 指令功能:从8为端口读入一个字节到AL寄存器,或从16为端口读一个字到AX寄存器。16位端口由两个地址连续的8为端口组成,从16位端口输入时,先将给定端口中的字节送进AL,再把端口地址加1,然后将该端口中的字节读入AH。
-
IN指令有两种格式:
- 第一种格式,端口地址(00~FFH)直接包含在IN指令里,共允许寻址256个端口。由于8086CPU可以直接访问地址为0000 ~ FFFFH的 64K 个I/O端口,当端口地址号大于FFH时,必须用第二种寻址方式。
- 第二种格式,即先将端口号送入DX寄存器,再执行输入操作。
OUT输出指令
指令格式:
OUT AL, 端口地址
或
OUT AX, 端口地址
端口地址存放在DX寄存器中
OUT AL, DX
或
OUT AX, DX
- 指令功能:将AL中一个字节写到一个8位端口或把AX中的一个字写到一个16位端口。同样对16位端口进行输出操作时,也是对两个连续的8位端口进行输出操作。
如下所示,读取系统的月份并显示。
assume cs:code, ds:data, ss:stack
data segment
db 128 dup(0)
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
start: mov ax, stack
mov ss, ax
mov sp, 128
call init_reg
call show_month
mov ax, 4C00H
int 21H
;====================================================
init_reg: mov bx, 0B800H
mov es, bx
ret
;==========================================================
show_month: mov al, 8 ; 月的内存地址
out 70H, al ; 1 2 1 + 30H '0'
in al, 71H ; 0001 0010 ah 0000 0001B
mov ah, al
shr ah, 1
shr ah, 1
shr ah, 1
shr ah, 1
and al , 00001111B
add ah, 30H
add al, 30H
mov di, 160 * 10 + 40 * 2
mov es:[di], ah
mov es:[di + 2], al
ret
code ends
end start
时间信息的
秒 | 分 | 小时 | 日 | 月 | 年 |
---|---|---|---|---|---|
0 | 2 | 4 | 7 | 8 | 9 |
BCD 码
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
---|---|---|---|---|---|---|---|---|---|
0000 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 |
以下是在DOSBOX中显示系统当前时间并实时刷新的程序代码
; 以年/月/日 时: 分: 秒的 形式显示当前的日期和时间
assume cs:code, ds:data, ss:stack
data segment
db 128 dup(0)
data ends
stack segment stack
db 128 dup(0)
stack ends
code segment
TIME_STYLE db 'YY/MM/DD HH:MM:SS', 0 ; y = year m = month d = day
; h = hour m = minute s = second
TIME_CMOS db 9, 8, 7, 4, 2, 0
start: mov ax, stack
mov ss, ax
mov sp, 128
call init_reg
call show_clock
mov ax, 4C00H
int 21H
;====================================================
show_clock: call show_time_style
showTime: mov si, OFFSET TIME_CMOS
mov di, 160 * 10 + 30 * 2
mov cx, 6
showDate: mov al, ds:[si]
out 70H, al
in al, 71H
mov ah, al ; 0011 0000
shr ah, 1
shr ah, 1
shr ah, 1
shr ah, 1
and al, 00001111B
add ah, 30H
add al, 30H
mov es:[di], ah
mov es:[di + 2], al
inc si
add di, 6
loop showDate
jmp showTime ; 键盘中断
ret
;=====================================================
init_reg: mov bx, 0B800H
mov es, bx
mov bx, cs
mov ds, bx
ret
;==========================================================
show_string: push dx
push ds
push es
push si
push di
showString: mov dl, ds:[si]
cmp dl, 0
je showStringRet
mov es:[di], dl
add di, 2
inc si
jmp showString
showStringRet: pop di
pop si
pop es
pop ds
pop dx
ret
;==========================================
show_time_style:
mov si, OFFSET TIME_STYLE
mov di, 160 * 10 + 30 * 2
call show_string
ret
code ends
end start
版权声明:本文为qq_44989881原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。