汇编 输入输出指令

Posted ʚVVcatɞ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了汇编 输入输出指令相关的知识,希望对你有一定的参考价值。

输入输出指令用来完成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

在这里插入图片描述
时间信息的

小时
024789

BCD 码

0123456789
0000000100100011010001010110011110001001

以下是在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	

在这里插入图片描述

以上是关于汇编 输入输出指令的主要内容,如果未能解决你的问题,请参考以下文章

汇编语言入门-总结

汇编学习笔记(10)-IO端口与指令

汇编指令

《Linux内核 核心知识全解析(完)》

汇编指令集

x86汇编指令集