微机原理与接口实验代码
实验一
TCP01-1
;支持子程序库的简化段源程序格式
include io.inc
.model small ; 定义程序的存储模式
.stack ; 定义堆栈段(默认是1KB空间)
.data ;数据段
msg byte 'Hello, Assembly!',13,10,0;定义要显示的字符串,注意结尾字符
.code ;代码段
start: mov ax,@data
mov ds,ax
mov ax,offset msg
call dispmsg
.exit 0
end start
TCP01-2
;***************************
;存储器读写,读写ASCII可显示字符
;段地址0d000, 偏移地址6000H~7FFFH,即从0d000:6000H开始
;***************************
include io.inc
.model small ; 定义程序的存储模式
.stack ; 定义堆栈段(默认是1KB空间)
.data
msg byte 'press any key to show the contents!',0dh,0ah,0
.code
start: mov ax,@data
mov ds,ax
mov ax,0d000h
mov es,ax
mov bx,6000h
mov cx,12 ;可显示ASCII码个数
mov al,20h ;空格' '=20h
write:
mov es:[bx],al
inc bx
inc al
loop write
mov ax,offset msg
call dispmsg
call readc
mov ax,0d000h
mov es,ax
mov bx,06000h
mov cx,12
read:
mov al,es:[bx]
call dispc
inc bx
loop read
delay proc ;延时子程序
push bx
push cx
mov bx,200
delay1: mov cx,0
delay2: loop delay2
dec bx
jne delay1
pop cx
pop bx
ret
delay endp
.exit 0
end start
实验四
TCP04-1
;*******************************;
;* 中断实验IRQ3 *;
;*******************************;
include io.inc
.model small ; 定义程序的存储模式
.stack ; 定义堆栈段(默认是1KB空间)
.data
msg byte 'TPCA interrupt No.3!',0dh,0ah,0
counter byte 0
intseg word ?
intoff word ?
intimr byte ?
.code
start: mov ax,@data
mov ds,ax
mov ax,350bh
int 21h
mov intseg,es
mov intoff,bx
;
cli
push ds
mov dx,offset intproc
mov ax,seg intproc
mov ds,ax
mov ax,250bh
int 21h
pop ds
;
in al,21h
mov intimr,al
and al,0f7h
out 21h,al
;
mov counter,0
sti
;
again: cmp counter,5
jb again
;
cli
mov al,intimr
out 21h,al
mov dx,intoff
mov ax,intseg
mov ds,ax
mov ax,250bh
int 21h
sti
.exit 0
intproc proc
sti
push ax
push si
push ds
;
mov ax,@data
mov ds,ax
;
inc counter
mov si,offset msg
call dpstri
;
mov al,20h
out 20h,al
pop ds
pop si
pop ax
iret
intproc endp
;
dpstri proc
push bx
disp1: mov al,[si]
test al,al
jz disp2
mov bx,0
mov ah,0eh
int 10h
inc si
jmp disp1
disp2: pop bx
ret
dpstri endp
end start
TCP04-2
;*******************************;
;* 中断实验IRQ10 *;
;*******************************;
include io.inc
.model small ; 定义程序的存储模式
.stack ; 定义堆栈段(默认是1KB空间)
.data
msg byte 'TPCA interrupt No.10!',0dh,0ah,0
counter byte 0
intseg word ?
intoff word ?
intimr byte ?
.code
start: mov ax,@data
mov ds,ax
mov ax,3572h ;!
int 21h
mov intseg,es
mov intoff,bx
;
cli
push ds
mov dx,offset intproc
mov ax,seg intproc
mov ds,ax
mov ax,2572h ;!
int 21h
pop ds
;
in al,0a1h ;!
mov intimr,al ;!
and al,0fbh ;!
out 0a1h,al ;!
;
mov counter,0
sti
;
again: cmp counter,5
jb again
;
cli
mov al,intimr
out 0a1h,al ;!
mov dx,intoff
mov ax,intseg
mov ds,ax
mov ax,2572h ;!
int 21h
sti
.exit 0
intproc proc
sti
push ax
push si
push ds
;
mov ax,@data
mov ds,ax
;
inc counter
mov si,offset msg
call dpstri
;
mov al,20h
out 0a0h,al ;!
out 20h,al
pop ds
pop si
pop ax
iret
intproc endp
;
dpstri proc
push bx
disp1: mov al,[si]
test al,al
jz disp2
mov bx,0
mov ah,0eh
int 10h
inc si
jmp disp1
disp2: pop bx
ret
dpstri endp
end start
TCP04-3
;*******************************;
;* 中断嵌套实验 *;
;*******************************;
include io.inc
.model small ; 定义程序的存储模式
.stack ; 定义堆栈段(默认是1KB空间)
.data
msg byte 'TPCA interrupt No.3!',0dh,0ah,0
msg1 byte 'TPCA interrupt No.3 again!',0dh,0ah,0
msg10 byte 'TPCA interrupt No.10!',0dh,0ah,0
msg11 byte 'TPCA interrupt No.10 again!',0dh,0ah,0
counter byte 0
counter10 byte 0
intseg word ?
intoff word ?
intimr byte ?
intseg10 word ?
intoff10 word ?
intimr10 byte ?
.code
start: mov ax,@data
mov ds,ax
mov ax,350bh
int 21h
mov intseg,es
mov intoff,bx
mov ax,3572h ;!
int 21h
mov intseg10,es
mov intoff10,bx
;
cli
push ds
mov dx,offset intproc
mov ax,seg intproc
mov ds,ax
mov ax,250bh
int 21h
mov dx,offset intproc10
mov ax,seg intproc10
mov ds,ax
mov ax,2572h ;!
int 21h
pop ds
;
in al,21h
mov intimr,al
and al,0f7h
out 21h,al
in al,0a1h ;!
mov intimr10,al ;!
and al,0fbh ;!
out 0a1h,al ;!
;
mov counter,0
mov counter10,0
sti
;
again: cmp counter,5
jb again
cmp counter10,5
jb again
;
cli
mov al,intimr
out 21h,al
mov dx,intoff
mov ax,intseg
mov ds,ax
mov ax,250bh
int 21h
mov al,intimr10
out 0a1h,al ;!
mov dx,intoff10
mov ax,intseg10
mov ds,ax
mov ax,2572h ;!
int 21h
sti
.exit 0
intproc proc
sti
push ax
push si
push ds
;
mov ax,@data
mov ds,ax
;
inc counter
mov si,offset msg
call dpstri
call delay
mov si,offset msg1
call dpstri
;
mov al,20h
out 20h,al
pop ds
pop si
pop ax
iret
intproc endp
intproc10 proc
sti
push ax
push si
push ds
;
mov ax,@data
mov ds,ax
;
inc counter10
mov si,offset msg10
call dpstri
;
call delay
mov si,offset msg11
call dpstri
mov al,20h
out 0a0h,al ;!
out 20h,al
pop ds
pop si
pop ax
iret
intproc10 endp
;
dpstri proc
push bx
disp1: mov al,[si]
test al,al
jz disp2
mov bx,0
mov ah,0eh
int 10h
inc si
jmp disp1
disp2: pop bx
ret
dpstri endp
delay proc ;延时子程序
push bx
push cx
mov bx,2000
delay1: mov cx,0
delay2: loop delay2
dec bx
jne delay1
pop cx
pop bx
ret
delay endp
end start
实验五
TCP05-1
;*************************;
;* 8253方式0计数器实验 *;
;*************************;
include io.inc
.model small
.stack
.data
.code
start:
mov al,10h ;设置8253通道0为工作方式0,二进制计数
mov dx,283h
out dx,al
mov dx,280h ;送计数初值为5
mov al,5
out dx,al
mov ah,al ;用于避免重复显示计数值
again: call wait
in al,dx ;读计数值
cmp al,ah ;用于避免重复显示计数值
jz again ;用于避免重复显示计数值
push ax
call dispuib ;调显示子程序
call dispcrlf
pop ax
mov ah,al ;用于避免重复显示计数值
cmp al,0
jnz again
.exit 0 ;退出
wait proc
push cx
mov cx,1000
wait1: loop wait1
pop cx
ret
wait endp
end start
TCP05-2
;*******************
;* 8253分频 *
;*******************
include io.inc
.model small
.stack
.data
.code
start:
mov dx,283h ;向8253写控制字
mov al,36h ;使通道0为工作方式3
out dx,al
mov ax,1000 ;写入循环计数初值1000
mov dx,280h
out dx,al ;先写入低字节
mov al,ah
out dx,al ;后写入高字节
;
mov dx,283h
mov al,76h ;设8253通道1工作方式3
out dx,al
mov ax,1000 ;写入循环计数初值1000
mov dx,281h
out dx,al ;先写低字节
mov al,ah
out dx,al ;后写高字节
.exit 0 ;程序退出
end start
TCP05-3
;********************************
;* 8253定时1秒中断,显示信息 *
;********************************
; include io.inc
.model small
.stack
.data
msg byte 'Press any key to exit.',0
led byte 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码
buf byte 0,0,0,0 ;存放要显示数字
counter byte 0
intseg word ?
intoff word ?
intimr byte ?
.code
start: mov ax,@data
mov ds,ax
mov ax,350bh
int 21h
mov intseg,es
mov intoff,bx
;
cli
push ds
mov dx,offset intproc
mov ax,seg intproc
mov ds,ax
mov ax,250bh
int 21h
pop ds
;
in al,21h ;读主片IMR
mov intimr,al ;给变量intimr
and al,0f7h ;设置1111 0111,允许IRQ3中断
out 21h,al ;输出设置允许IRQ3中断
;
mov dx,283h ;向8253写控制字
mov al,36h ;使通道0为工作方式3 0011 0110 计数器零 先高后低 方式3 二进制
out dx,al
mov ax,1000 ;写入循环计数初值1000
mov dx,280h ;给计数器0
out dx,al ;先写入低字节
mov al,ah
out dx,al ;后写入高字节
;
mov dx,283h
mov al,76h ;设8253通道1工作方式3
out dx,al
mov ax,1000 ;写入循环计数初值1000(clk 1MHZ,周期1000*10e-6=10e-3 s)
mov dx,281h ;写到计数器0
out dx,al ;先写低字节
mov al,ah
out dx,al ;后写高字节
;
mov byte ptr counter,0
sti
;
again: cmp byte ptr counter,3600 ;中断五次
jb again
;
cli
mov al,intimr ;恢复IMR
out 21h,al
mov dx,intoff ;恢复中断服务程序
mov ax,intseg
mov ds,ax
mov ax,250bh
int 21h
sti
.exit 0
intproc proc
sti
push ax
push si
push ds
;
mov ax,@data
mov ds,ax
;
inc byte ptr counter ;设置增量
mov dx,28bh ;将8255设为A和B口输出
mov al,80h
out dx,al
mov al,0 ;控制端口B为低,关掉数码管显示
mov dx,289h
out dx,al
start1:
xor si,si
mov ah,08h ;位码---初始千位开始0000 1000
again:
mov bl,buf[si] ;bl为要显示的数--0
mov bh,0
mov al,led[bx] ;求出对应的led数码--3fh
mov dx,288h ;自8255的端口A输出
out dx,al ;显示什么数字
mov al,ah ;使一个数码管亮
mov dx,289h
out dx,al ;显示什么位
call delay ;延时
;
mov al,0 ;关掉数码管显示
mov dx,289h
out dx,al
;
inc si ;下一个要显示的数字--第二个0
shr ah,1 ;下一个显示的位--百位
jnz again
;
mov bl,buf+3 ;要显示的数加1
inc bl ;0001
cmp bl,10 ;加到10
jb next3 ;没有继续个位加1
mov bl,0 ;加到10,进位
mov bh,buf+2 ;十位进一
inc bh ;十位
cmp bh,6 ;十位是否进位
jb next2
mov bh,0
mov cl,buf+1
inc cl
cmp cl,10
jb next1
mov cl,0
mov ch,buf
inc ch
cmp ch,6
jb next0
mov ch,0 ;循环从0000开始了
next0: mov buf,ch ;千位
next1: mov buf+1,cl ;百位
next2: mov buf+2,bh ;十位
next3: mov buf+3,bl ;个位
;
; call readkey
; jz start1 ;没有键按下则继续循环显示,jnz有键按下则退出
mov al,0 ;关掉数码管显示
mov dx,289h
out dx,al
;
mov al,20h ;设置结束
out 20h,al
pop ds
pop si
pop ax
iret
intproc endp
;
delay proc ;延时
push cx
mov cx,10000
delay1: loop delay1
pop cx
ret
delay endp
end start
实验六
TCP06-1
;*******************************;
;* 8255方式0的C口输入,A口输出 *;
;*******************************;
include io.inc
.model small
.stack
.data
msg byte 'Connect correctly, Press anykey to see.',0
.code
start:
mov ax,@data
mov ds,ax
mov ax,offset msg
call dispmsg
again: call readkey ;判断是否有按键
jz again ;若无
mov dx,28bh ;设8255为C口输入,A口输出
mov al,8bh
out dx,al
inout:
mov dx,28ah ;从C口输入一数据
in al,dx
mov dx,288h ;从A口输出刚才自C口所输入的数据
out dx,al
.exit 0 ;否则返回
end start
TCP06-2
;*******************************;
;* 8255方式1输出,中断方式 *;
;*******************************;
include io.inc
.model small
.stack
.data
counter byte 0
outdata byte 0
intseg word ?
intoff word ?
intimr byte ?
.code
start: mov ax,@data
mov ds,ax
mov ax,350bh
int 21h
mov intseg,es
mov intoff,bx
;
cli
push ds
mov dx,offset intproc
mov ax,seg intproc
mov ds,ax
mov ax,250bh
int 21h
pop ds
;
in al,21h
mov intimr,al
and al,0f7h
out 21h,al
;
mov counter,0
mov outdata,01h
; 8255初始化
mov dx,28bh
mov al,0a0h
out dx,al
mov al,0dh
out dx,al
mov al,0 ;输出一个数据(才能引起中断)
mov dx,288h
out dx,al
sti
;
again: cmp counter,8
jb again
;
cli
mov al,intimr
out 21h,al
mov dx,intoff
mov ax,intseg
mov ds,ax
mov ax,250bh
int 21h
sti
.exit 0
intproc proc
sti
push ax
push dx
push ds
;
mov ax,@data
mov ds,ax
;
inc counter
mov al,outdata
mov dx,288h
out dx,al
shl al,1
mov outdata,al
;
mov al,20h
out 20h,al
pop ds
pop dx
pop ax
iret
intproc endp
end start
TCP06-3
;*******************************;
;* 8255方式1输入 *;
;*******************************;
include io.inc
.model small
.stack
.data
counter byte 0
intseg word ?
intoff word ?
intimr byte ?
.code
start: mov ax,@data
mov ds,ax
mov ax,350bh
int 21h
mov intseg,es
mov intoff,bx
;
cli
push ds
mov dx,offset intproc
mov ax,seg intproc
mov ds,ax
mov ax,250bh
int 21h
pop ds
;
in al,21h
mov intimr,al
and al,0f7h
out 21h,al
;
mov counter,0
; 8255初始化
mov dx,28bh
mov al,0b8h
out dx,al
mov al,09h
out dx,al
sti
;
again: cmp counter,5
jb again
;
cli
mov al,intimr
out 21h,al
mov dx,intoff
mov ax,intseg
mov ds,ax
mov ax,250bh
int 21h
sti
.exit 0
intproc proc
sti
push ax
push dx
push ds
;
mov ax,@data
mov ds,ax
;
inc counter
mov dx,288h
in al,dx
call dispbb
call dispcrlf
;
mov al,20h
out 20h,al
pop ds
pop dx
pop ax
iret
intproc endp
end start
实验八
TCP08-1
;***************************
;* LED数码管一位静态显示 *
;***************************
include io.inc
.model small
.stack
.data
led byte 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码
msg byte 0dh,0ah,'Input a number (0--9), other key exit.',0dh,0ah,0
.code
start: mov ax,@data
mov ds,ax
mov dx,28bh ;使8255的A口为输出方式
mov ax,80h
out dx,al
again:
mov ax,offset msg ;显示提示信息
call dispmsg
call readc ;从键盘接收字符
cmp al,'0' ;是否小于0
jb done ;若是则退出
cmp al,'9' ;是否大于9
ja done ;若是则退出
sub al,30h ;将所得字符的ASCII码减30H
mov bx,offset led ;bx为数码表的起始地址
xlat ;求出相应的段码
mov dx,288h ;从8255的A口输出
out dx,al
jmp again
done:
.exit 0 ;返回
end start
TCP08-2
;************************************
;* LED数码管多位动态显示"3456" *
;************************************
include io.inc
.model small
.stack
.data
led byte 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码
buf byte 3,4,5,6 ;存放要显示的数字
msg byte 'Press any key to exit.',0
.code
start: mov ax,@data
mov ds,ax
mov ax,offset msg
call dispmsg
mov dx,28bh ;将8255设为A和B口输出
mov al,80h
out dx,al
mov al,0 ;控制端口B为低,关掉数码管显示
mov dx,289h
out dx,al
start1: xor si,si
mov ah,08h ;位码
again:
mov bl,buf[si] ;bl为要显示的数
mov bh,0
mov al,led[bx] ;求出对应的led数码
mov dx,288h ;自8255的端口A输出
out dx,al
mov al,ah ;使一个数码管亮
mov dx,289h
out dx,al
call delay ;延时
;
mov al,0 ;关掉数码管显示
mov dx,289h
out dx,al
;
inc si
shr ah,1
jnz again
;
call readkey
jz start1 ;有键按下则退出
.exit 0 ;返回
delay proc ;延时
push cx
mov cx,10000
delay1: loop delay1
pop cx
ret
delay endp
end start
TCP08-4
;**************************************
;* LED数码管多位循环显示"0000-9999" *
;**************************************
include io.inc
.model small
.stack
.data
led byte 3fh,06h,5bh,4fh,66h,6dh,7dh,07h,7fh,6fh ;段码
buf byte 0,0,0,0 ;存放要显示数字
msg byte 'Press any key to exit.',0
.code
start: mov ax,@data
mov ds,ax
mov ax,offset msg
call dispmsg
mov dx,28bh ;将8255设为A和B口输出
mov al,80h
out dx,al
mov al,0 ;控制端口B为低,关掉数码管显示
mov dx,289h
out dx,al
start1:
xor si,si
mov ah,08h ;位码
again:
mov bl,buf[si] ;bl为要显示的数
mov bh,0
mov al,led[bx] ;求出对应的led数码
mov dx,288h ;自8255的端口A输出
out dx,al
mov al,ah ;使一个数码管亮
mov dx,289h
out dx,al
call delay ;延时
;
mov al,0 ;关掉数码管显示
mov dx,289h
out dx,al
;
inc si
shr ah,1
jnz again
;
mov bl,buf+3 ;要显示的数加1
inc bl
cmp bl,10
jb next3
mov bl,0
mov bh,buf+2
inc bh
cmp bh,10
jb next2
mov bh,0
mov cl,buf+1
inc cl
cmp cl,10
jb next1
mov cl,0
mov ch,buf
inc ch
cmp ch,10
jb next0
mov ch,0
next0: mov buf,ch
next1: mov buf+1,cl
next2: mov buf+2,bh
next3: mov buf+3,bl
;
call readkey
jz start1 ;有键按下则退出
mov al,0 ;关掉数码管显示
mov dx,289h
out dx,al
.exit 0 ;返回
delay proc ;延时
push cx
mov cx,10000
delay1: loop delay1
pop cx
ret
delay endp
end start
实验十
TCP10-1
;*****************************************;
;*接收A/D转换器数据在屏幕上显示,延时方式*;
;*****************************************;
include io.inc
.model small
.stack
.data
msg byte 'Press any key to exit.',13,10,0
.code
start: mov ax,@data
mov ds,ax
mov ax,offset msg
call dispmsg
again: mov dx,298h ;启动A/D转换器
out dx,al
call delay ;延时
in al,dx ;从A/D转换器输入数据
call disphb ;显示数据
mov al,20h
call dispc
mov al,20h ;加空格,分隔显示的数据
call dispc
call readkey
je again ;有键按下则退出
.exit 0 ;返回
delay proc ;延时子程序
push bx
push cx
mov bx,200
delay1: mov cx,0
delay2: loop delay2
dec bx
jne delay1
pop cx
pop bx
ret
delay endp
end start
TCP10-2
;*****************************************;
;*接收A/D转换器数据在屏幕上显示,查询方式*;
;*****************************************;
include io.inc
.model small
.stack
.data
msg byte 'Press any key to exit.',13,10,0
.code
start: mov ax,@data
mov ds,ax
mov ax,offset msg
call dispmsg
mov dx,28bh ;8255初始化,PC7连接A/D转换器的EOC
mov al,88h
out dx,al
again: mov dx,298h ;启动A/D转换器
out dx,al
poll: call wait
mov dx,28ah
in al,dx
test al,80h
jz poll
mov dx,298h
in al,dx ;从A/D转换器输入数据
call disphb ;显示数据
mov al,20h
call dispc
mov al,20h ;加空格,分隔显示的数据
call dispc
call readkey
je again ;有键按下则退出
.exit 0 ;返回
wait proc
push cx
mov cx,1000
wait1: loop wait1
pop cx
ret
wait endp
end start
TCP10-3
;*****************************************;
;*接收A/D转换器数据在屏幕上显示,中断方式*;
;*****************************************;
include io.inc
.model small
.stack
.data
eoc byte 0 ;读取标志
;主程序启动转换后设置为0,表示还没有中断、读取转换数字
;中断服务程序读取转换数字后设置为1,表示可以开始新的转换
addata byte ?
msg byte 'Press any key to exit.',13,10,0
.code
start: mov ax,@data
mov ds,ax
mov ax,offset msg
call dispmsg
cli
mov ax,350bh
int 21h
push es
push bx
;
push ds
mov dx,offset adint
mov ax,seg adint
mov ds,ax
mov ax,250bh
int 21h
pop ds
;
in al,21h
push ax
and al,0f7h
out 21h,al
sti
;
start1:
mov dx,298h ;启动A/D转换器
out dx,al
mov eoc,0
again: call readkey
jne done ;有键按下则退出
cmp eoc,0
jz again
mov al,addata ;获取中断服务程序放置的数据
call disphb ;显示数据
mov al,20h
call dispc
mov al,20h ;加空格,分隔显示的数据
call dispc
jmp start1
;
done: cli
pop ax
out 21h,al
pop dx
pop ax
push ds
mov ds,ax
mov ax,250bh
int 21h
pop ds
sti
;
.exit 0
;
adint proc
sti
push ax
push dx
push ds
mov ax,@data
mov ds,ax
mov dx,298h
in al,dx ;从A/D转换器输入数据
mov addata,al ;保存数据
mov eoc,1 ;设置标志
mov al,20h
out 20h,al
pop ds
pop dx
pop ax
iret
adint endp
;
end start