汇编 输入输出指令

  • Post author:
  • Post category:其他


输入输出指令用来完成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 版权协议,转载请附上原文出处链接和本声明。