| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1435 人关注过本帖
标题:日,刚考完微机....
只看楼主 加入收藏
tianykun
Rank: 4
等 级:禁止访问
威 望:11
帖 子:3727
专家分:0
注 册:2005-11-13
收藏
得分:0 
include var.asm ;定义的相关变量的汇编程序
.code
; main 主程序
; 功能描述:每隔一定时间在屏幕上显示一段字符
main proc far ;远过程
mov ax,@code
mov ds,ax ;把程序开始的段地址送到数据段寄存器cli ; 设置前关闭所以中断以防止干扰
call ini_8255 ; 调用初始化8255的子程序
call ini_key2 ; 初始化按键2的子程序
call ini_key1 ; 初始化按键1的子程序
call ini_8253 ; 初始化8253的子程序
call ini_8259 ; 初始化8259的子程序
mov al,20h ; 8259的工作命令字OCW2,表示中断结束为非特殊EOI模式,决定中断请求级别为0
out 20h,al
sti ; 重新打开中断
A2:nop
jmp A2
include ini.asm ;包含进相关8255,8253,8259 的初始化程序,这样才可以调用
include event.asm ;包含进中断相关程序,这样中断才有服务程序
hlt
main endp ;相当于main函数结束
;*********************************
; 按键key2中断程序:IRQ_key2
; 功能描述:相应7号中断(key2),对计数单元完成加一的操作,并为显示作准备
;*********************************
IRQ_key2 proc near
cli push ax push bx push cx push dx push ds
push es push di push si push bp
mov ax,@data ;取得原来的数据段?
mov ds,ax
call EVENT_key2 ;调用按钮key2加1操作
IRQ_key2_exit: ;中断的退出点
mov al,20h out 20h,al pop bp pop si pop di pop es pop ds pop cx
pop bx pop ax
sti ;开中断 iret
IRQ_key2 endp
; 按键key1中断程序:IRQ_key1
; 功能描述:相应7号中断(key1),对计数单元完成减一的操作,并为显示作准备
IRQ_key1 proc near
cli ;关中断 push ax push bx push cx push dx push ds push es push di push si push bp
mov ax,@data ;取得原来的数据段
mov ds,ax
call EVENT_key1 ;调用按钮key1减1操作
IRQ_key1_exit: ;中断的退出点
mov al,20h
out 20h,al pop bp pop si pop di pop es pop ds pop dx pop cx
pop bx pop ax
sti ;开中断 iret
IRQ_key1 endp
; 8253 中断子程序
; 功能描述:8253的定时器0的初始化值为1000,说明计数从1000计到0就产生一次实时时钟中断,计完1000就是1毫秒(1ms),说明机器频率为1M,时钟频率为12M。然而本程序是让8253每产生5次中断才有一次事件处理(数码管某个位显示该数位的值),即数码管的扫描速率是5ms(毫秒)
IRQ_8253 proc near
Cli push ax push bx push cx push dx push ds push es push di
push si push bp
mov ax,@data
mov ds,ax
mov ax,time0_counter ;取得当前的计数器值
cmp ax, TIME0_MAX ;判断是否达到了规定的阀值5毫秒
jl skip_8253 ;小于0转移,如果达到了阀值就清零并调用显示程序,如果没有到达就计数器加1返回
mov time0_counter,0000h ;如果等于5毫秒,即计算结果不小于0则计数器清零
call EVENT_8253 ;调用显示程序
skip_8253: inc time0_counter ;计数器加1
mov al,20h ;中断结束
out 20h,al
pop bp pop si pop di pop es pop ds pop dx pop cx pop b pop ax sti iret
IRQ_8253 endp end
; EVENT_key2子程序-------------------------------------------------------------EVENT 事件
; 功能描述:处理将数据加一的操作(提示:key2按一下才会加1,不按则不加,所以本程序要在按一下中断一次才执行一次的)
EVENT_key2 proc near
;-------------将计数器加1,求得计数器的符号与绝对值,为后面的处理作准备
lea si,data_buffer ;地址传送指令,把data_buffer的有效地址传送到si,si中的值为data_buffer的偏移地址
mov cx,4
;---------------------------------------------- 只执行加1动作
add_loop1:
inc byte ptr ds:[si] ;位数内容加1
cmp byte ptr ds:[si],0ah ;比较指令,ds:[si]操作数减去0ah,结果送到ds:[si]
jne max_test1 ;运算结果不相等转移,ZF=0即要一直加到和10相等
mov byte ptr ds:[si],0 ;如果加到等于10了,si的本位清0
inc si ;转移到高一位位数
dec cx jne add_loop1 ;只能执行四次
;---------------------------------------------- 数位显示的数和数值之间关系的处理的准备
max_test1: mov tep,0000h ;把0000h传到求和的暂时存储器,因为它只是一个数字中转器,所以每次都要清0后再能用
mov cx,4
lea si,data_buffer ;地址传送指令,把data_buffer的有效地址传送到si,si中的值为data_buffer的偏移地址
lea di, mul_times ;把计算的乘数的地址给di
;------- 数位显示的数和数值之间关系的处理,数位显示的数和数值在这里还有本质上区别
max_test_loop1: mov ah,0 ;
mov al,byte ptr ds:[si];
mov bx, ds:[di] ;乘数
mul bx ;al乘以bx,结果送到ax(和dx)
add ax,tep ;把相乘结果和和暂时存储器tep相加结果送到ax
mov tep,ax ;再把ax结果送到tep,好让本循环的最后的数可以和MAX_VALUE比较
inc si inc di ;
inc di dec cx
jne max_test_loop1 ;只能执行四次
;---------------------------------------------- 获取和数
get_sum: cmp tep, MAX_VALUE ;和最大值1000比较
jne key2_skip ;不相等转移马上退出
;-------- 若和1000相等,即是最大值了,应该先清0再退出,下面两行是清0之前做的准备
mov cx,4 lea si,data_buffer ;
;---------------------------------------------- 所有显示位清0
clear_loop1: mov byte ptr ds:[si],0;和最大值相等了,每个数位都清0
inc si ;dec cx ;
jne clear_loop1 ;只能执行四次
key2_skip: ret
EVENT_key2 endp
; EVENT_key1子程序
; 功能描述:处理将数据加一的操作(提示:key1按一下才会减1,不按则不减,所以本程序要在按一下中断一次才执行一次的)
EVENT_key1 proc near
;--------------------- 将计数器减1,求得计数器的符号与绝对值,为后面的处理作准备
lea si,data_buffer ;地址传送指令,把data_buffer的有效地址传送到si,si中的值为data_buffer的偏移地址
mov cx,4
;---------------------------------------------- 只执行减1动作
add_loop2: dec byte ptr ds:[si] ;位数内容减1
cmp byte ptr ds:[si],0 ;比较指令,ds:[si]操作数减去0,结果送到ds:[si]
jnl max_test2 ;运算结果不小于转移,SF=0(不小于转移),即要一直减0
mov byte ptr ds:[si],09h ;如果减到小于0了,si的本位置为9
inc si ;转移到高一位位数
dec cx jne add_loop2 ;只能执行四

离开这里,离开你的视野,归隐到属于我的地方,无论何处
2007-01-10 14:47
tianykun
Rank: 4
等 级:禁止访问
威 望:11
帖 子:3727
专家分:0
注 册:2005-11-13
收藏
得分:0 
;---------------------------------------------- 数位显示的数和数值之间关系的处理的准备
max_test2: mov tep,0000h ;把0000h传到求和的暂时存储器,因为它只是一个数字中转器,所以每次都要清0后再能用
mov cx,4 lea si,data_buffer lea di, mul_times ;把计算的乘数的地址给di
;-- 数位显示的数和数值之间关系的处理,数位显示的数和数值在这里还有本质上区别
max_test_loop2: mov ah,0 ;
mov al,byte ptr ds:[si];
mov bx, ds:[di] ;乘数
mul bx ;al乘以bx,结果送到ax(和dx)
add ax,tep ;把相乘结果和和暂时存储器tep相加结果送到ax
mov tep,ax ;再把ax结果送到tep,好让本循环的最后的数可以和最大值比较
inc si ;增加到高一位的显示数据地址
inc di inc di ;因为乘数在变量定义文件var.asm中是字增加到高一位乘数
dec cx
jne max_test_loop2 ;只能执行四次
;---------------------------------------------- 获取差数
get_margin: cmp tep, MIN_VALUE ;和最小值0比较
jne key1_skip ;不相等转移马上退出
;- 和0相等,即是最小值了,应该将其置为1000再退出,下面两行为置为1000做的准备
mov cx,3
lea si,data_buffer
;---------------------------------------------- 置为1000
clear_loop2: mov byte ptr ds:[si],0;和最小值相等了,为了置为1000,前三个为0
inc si ;dec cx ;
jne clear_loop2 ;只能执行三次
mov byte ptr ds:[si],1 ;第4个置为1才能成为1000
key1_skip: ret
EVENT_key1 endp
; EVENT_8253子程序
; 功能描述:CPU把各位数转化为数码管的7段显示规则码发送到8255的IO端口,然后通过IO端口连接到数码管来显示
EVENT_8253 proc near
mov bp,show_number ;显示的控制字,PA口用
lea si,data_buffer 把data_buffer的有效地址传送到si,si中的值为data_buffer的偏移地址
mov al,byte ptr ds:[si+bp];数码管各数位的值
mov ah,0
mov bp,ax ;把各位的数送到bp
lea si,number_led
mov al,byte ptr ds:[si+bp];把数字对应的字型码传送给al
out PB,al ;把字型码al直接传到8255的PB口,PB口接的数码管的字型线,控制数码管的字型,控制哪一位上的字形
mov cx,show_number ;控制字传到待移位寄存器的移位数寄存器里
mov ax,0001h
rol ax,cl ;左循环移位,一次移动cl位,
inc show_number ;自增1,轮到左边数码管显示
cmp show_number,0004h ;和4相等相当于要到第五个管,这里没有第五个管,所以下面清0
jne not_reach_head ;不相等转移
mov show_number,0 ;4个管都显示了,回到第一个管的位线控制字值
not_reach_head: not al ;取反让其位线值为0就显示
out PA,al ;输出到8255的PA口,PA口接的数码管的字位线控制数码管的字位 PA控制哪一位亮
ret ;返回
EVENT_8253 endp
; ini_8259 初始化8259子程序---------------------------------------------------------INT部分
ini_8259 proc near ;近过程
in al,21h
and al,OPEN_INT0 ;开启中断0
out 21h,al ;CPU把控制信号输出到21端口
in al,21h and al,OPEN_INT7 ;开启中断7
out 21h,al in al,21h
and al,OPEN_INT6 ;开启中断6
out 21h,al ret
ini_8259 endp
;*********************************
; ini_8253 子程序
ini_8253 proc near
mov ax,0 ;设置附加段到中断向量表,设置中断向量表的段地址为0000h
mov es,ax
;------------- 修改8253中断向量偏移地址
mov di,INT0_VECTOR_OFFSET ; 获得8253(即8259中断0)在中断向量表的偏移地址的指针
mov ax, offset IRQ_8253 ;获得8253(即8259中断0)中断程序的偏移地址
mov es:[di],ax ;将8253(即8259中断0)中断向量的偏移地址指向自定义8253中断程序(IRQ_8253)
;------------- 修改8253中断向量段地址
mov di,INT0_VECTOR_SEGMENT ;获得8253(即8259中断0)在中断向量表的段地址的指针
mov ax, @code 获得8253(即8259中断0)中断程序的段地址
mov es:[di],ax ;将8253(即8259中断0)中断向量的段地址指向自定义8253中断程序(IRQ_8253)
;----------------------------- 定时器0赋初值,即初始化
mov al,TIME_SEL_0 ;写控制字到8253控制寄存器,选择0号通道
out TCTR ,al mov al,TIME0_LOW ;低位数据(0e8h)到定时器0寄存器
out T0,al
mov al,TIME0_HIGH ;写高位数据(03h)到定时器0的数据寄存器
out T0,al ret
ini_8253 endp
;********************************
; ini_key2 子程序;********************************
ini_key2 proc near
mov ax,PRGRAM_SEGMENT mov es,ax ;--------------- 修改中断向量,将中断程序指向自定义中断程序,key2的接口
mov ax, offset IRQ_key2 ;取得key2中断(8259中断7)程序入口偏移地址
mov di, INT7_VECTOR_OFFSET ;取得(8259中断7)中断向量表中的偏移地址指针
mov es:[di],ax ;替换偏移地址
mov ax,@code ;获得(8259中断7)程序的段地址
mov di,INT7_VECTOR_SEGMENT ;取得(8259中断7)中断向量表中的段地址指针
mov es:[di],ax ;替换段地址
ini_key2 endp
;********************************
; ini_key1 子程序;********************************
ini_key1 proc near
mov ax,PRGRAM_SEGMENT
mov es,ax ;- 修改中断向量,将中断程序指向自定义中断程序,key1的接口
mov ax, offset IRQ_key1 ;取得key1中断(8259中断6)程序入口偏移地址
mov di, INT6_VECTOR_OFFSET ;取得(8259中断6)中断向量表中的偏移地址指针
mov es:[di],ax ;替换偏移地址
mov ax,@code ;获得(8259中断6)程序的段地址
mov di,INT6_VECTOR_SEGMENT ;取得(8259中断6)中断向量表中的段地址指针
mov es:[di],ax ;替换段地址
ini_key1 endp
;*********************************
; ini_8255 子程序;*********************************
ini_8255 proc near
;-------------- 开始设置工作
mov al,CTR_SHOWONLY ;设置8255控制字
out PCTR,al mov al,0ffh
out PB,al ; 将字线全部开启
mov al,0 out PA,al ; 将位线开启
ret
ini_8255 endp
;**********************************--------------------------------------------VAR部分
; 常量定义
PRGRAM_OFFSET equ 2000H ;程序开始的偏移地址
PRGRAM_SEGMENT equ 0000H ;程序开始的段地址
INT7_VECTOR_OFFSET equ 003cH ;8259中断7在中断向量表中的偏移地址,用作Key2的中断触发
INT7_VECTOR_SEGMENT equ 003eH ;8259中断7在中断向量表中的段地址 , 用作Key2的中断触发
INT6_VECTOR_OFFSET equ 0038H ;8259中断6在中断向量表中的偏移地址,用作Key1的中断触发
INT6_VECTOR_SEGMENT equ 003aH ;8259中断6在中断向量表中的段地址 , 用作Key1的中断触发
INT0_VECTOR_OFFSET equ 0020H ;8259中断0在中断向量表中的偏移地址, 用作8253的0号通道中断
INT0_VECTOR_SEGMENT equ 0022H ;8259中断0在中断向量表中的段地址, 用作8253的0号通道中断
;****** 8259端口控制定义字,8259的工作命令字OCW1(中断屏蔽命令字)
MSAK_INT7 equ 10000000B ;8259中断屏蔽中断7用的字
OPEN_INT7 equ 01111111B ;8259中断开启中断7用的字
MSAK_INT0 equ 00000001B ;8259中断屏蔽中断0用的字
OPEN_INT0 equ 11111110B ;8259中断开启中断0用的字
MSAK_INT6 equ 01000000B ;8259中断屏蔽中断6用的字
OPEN_INT6 equ 10111111B ;8259中断开启中断6用的字
;*************************** 8255常量定义端口地址
PA equ 60h ;8255A口的I/O地址
PB equ 61h ;8255B口的I/O地址
PC equ 62h ;8255C口的I/O地址
PCTR equ 63h ;8255的控制I/O地址
;************************* 8255端口控制定义字
CTR_SHOWONLY equ 10000000B ;A口与B口都工作在方式0,C口全部输出, A口输出控制位线,B口输出控制字形,C口不使用
;*************************** 8253常量定义端口地址
T0 equ 40h ;8253定时器0号端口地址
T1 equ 41h ;8253定时器1号端口地址
T2 equ 42h ;8253定时器2号端口地址
TCTR equ 43h ;8253的控制端口地址
;************************* 8253端口控制定义字
TIME_SEL_0 equ 00111100B ;选择端口0,先控制低位,再控制高位,工作方式为2(方式2可作为一个脉冲速率发生器或用于产生实时时钟中断,本程序就是用来产生实时时钟中断),数据格式是二进制
TIME0_LOW equ 0e8h ;定时器0的数据的高位和低位,设置为1000,说明计数从1000计到0就产生实时时钟中断,计完1000,1毫秒(1ms),说明机器频率为1M,时钟频率为12M
TIME0_HIGH equ 03h
TIME0_MAX equ 5 ;定时器0计数的最大值
;************************** 定义的程序用常量
MAX_VALUE equ 1000 ;定义显示的最大值
MIN_VALUE equ 0 ;定义显示的最小值
; 变量量定义
time0_counter dw 0000h ;定时器0的计数器的值,每个单位代表一个毫秒,当大于阀制后清零
number_led db 03fh,06h,05bh,04fh,66h,06dh,07dh,07h,07fh,06fh ;显示的0--9的字型码
data_buffer db 00h,00h,00h,00h ;代表显示的数字共四位
show_number dw 0000h ;显示的控制字,PA口用
mul_times dw 1,10,100,1000 ;计算的乘数
tep dw 00 ;求和的暂时存储器


离开这里,离开你的视野,归隐到属于我的地方,无论何处
2007-01-10 14:47
tianykun
Rank: 4
等 级:禁止访问
威 望:11
帖 子:3727
专家分:0
注 册:2005-11-13
收藏
得分:0 
上面就是答案咯...

离开这里,离开你的视野,归隐到属于我的地方,无论何处
2007-01-10 14:48
tianykun
Rank: 4
等 级:禁止访问
威 望:11
帖 子:3727
专家分:0
注 册:2005-11-13
收藏
得分:0 
以下是引用yushui在2007-1-10 14:11:33的发言:
我刚考完英语 呵呵

你就开心咯...看你笑的样子.


离开这里,离开你的视野,归隐到属于我的地方,无论何处
2007-01-10 14:49
小天狼星
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:483
专家分:0
注 册:2006-11-1
收藏
得分:0 
拜托,那都是什么,tianykun你都能看懂吗?厉害,做不出题没关系,我连看都看不懂

[face=仿宋_GB2312]一生那么长,长不过时间定义下的永远;一生那么短,短不过人海中一次又一次匆忙的擦肩。[/face]
2007-01-10 14:50
棉花糖ONE
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:32
帖 子:2987
专家分:0
注 册:2006-7-13
收藏
得分:0 
这答案也太长了吧,你们考试都考这么难呢

26403021 sql群 博客 blog./user15/81152/index.shtml
2007-01-10 14:52
tianykun
Rank: 4
等 级:禁止访问
威 望:11
帖 子:3727
专家分:0
注 册:2005-11-13
收藏
得分:0 
老师给D答案..考完就给了.
汇编.
我不会做.没你厉害啊.

离开这里,离开你的视野,归隐到属于我的地方,无论何处
2007-01-10 14:53
tianykun
Rank: 4
等 级:禁止访问
威 望:11
帖 子:3727
专家分:0
注 册:2005-11-13
收藏
得分:0 
这个是最后一题,20分

离开这里,离开你的视野,归隐到属于我的地方,无论何处
2007-01-10 14:53
小天狼星
Rank: 3Rank: 3
等 级:新手上路
威 望:6
帖 子:483
专家分:0
注 册:2006-11-1
收藏
得分:0 
以下是引用tianykun在2007-1-10 14:53:02的发言:
老师给D答案..考完就给了.
汇编.
我不会做.没你厉害啊.

还说呢,汇编我一点都不会,你多少还接触过呢


[face=仿宋_GB2312]一生那么长,长不过时间定义下的永远;一生那么短,短不过人海中一次又一次匆忙的擦肩。[/face]
2007-01-10 14:54
棉花糖ONE
Rank: 7Rank: 7Rank: 7
等 级:贵宾
威 望:32
帖 子:2987
专家分:0
注 册:2006-7-13
收藏
得分:0 
我们考汇编,可能整张卷子写的都没你们一题多吧

26403021 sql群 博客 blog./user15/81152/index.shtml
2007-01-10 14:54
快速回复:日,刚考完微机....
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.018794 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved