微型计算机原理硬件实验,微机原理硬件实验一:跑马灯

本文针对:北邮微机原理硬件实验一,实验平台介绍和实验一IO的使用。用基于8086的汇编进行编程实验。

前半学期荒废,基本没学汇编语言,看着实验要求就一个头痛。

同学找来学长代码,成功救赎。

写下本文,以膜拜学长,并从中学习微原硬件实验编程方法。

实验要求

1.学习使用Debug命令,并用I、O命令直接对端口进行读写操作,

2.用汇编语言编写跑马灯程序。(使用EDIT编辑工具)实现功能

A.通过读入端口状态(ON为低电平),选择工作模式(灯的闪烁方式、速度等)。

B.通过输出端口控制灯的工作状态(低电平灯亮)

学长的代码

我就直接把学长的代码粘贴过来啦,保留了作者信息,学长会原谅我的。

; FILENAME : marquee.asm

; AUTHOR : XIAO, Zhiqing ( No. 13 , Cl. 07105 )

; DATE : 20091209

; MODIFIED: feichashao, 2013-12-7

; DESCRIPTION : revolving scenic lamps which shift in either direction

; USAGE : switchers -- ( SW0 is the most left one )

;   SW0 ( play ) :      UP exit         DOWN play

;   SW1 ( direction ):  UP right        DOWN left

;   SW2 ( pause ) :     UP pause        DOWN play

;   SW3 ( speed ) :     UP slow         DOWN fast

;   SW4 ( mode ) :      UP three lights DOWN one light

Data SEGMENT

SwState DB 0

LdState DB 0FEH

Buffer DB 0

Data ENDS

Stack SEGMENT STACK 'STACK'

DB 100H DUP(0)

Stack ENDS

Code SEGMENT

ASSUME   DS:Data,SS:Stack,CS:Code

Main PROC

PUSH DS

XOR  AX,AX

PUSH AX

MOV AX,Data

MOV DS,AX

MOV ldState,0FEh;initialize

CALL EndlessRepeat

RET;unreachable instruction

Main ENDP

EndlessRepeat PROC

EndlessLoop: CALL ProcToRepeat

JMP EndlessLoop

RET

EndlessRepeat ENDP

ProcToRepeat PROC

CALL readSw

CALL excuteDirection

CALL excuteMode

CALL excutePause

CALL excuteReturnToDos

CALL excuteSpeed

RET

ProcToRepeat ENDP

DivFreq PROC

PUSH CX

MOV  CX,1000H

MyLoop: PUSH CX

MOV  CX,8000H

MyNestedLoop:DEC CX

JNZ MyNestedLoop

POP CX

DEC CX

JNZ MyLoop

POP CX

RET

DivFreq ENDP

ReadSw PROC

PUSH AX

PUSH DX

MOV  DX,0E8E0H

IN   AL,DX

MOV  SwState,AL

POP  DX

POP AX

RET

ReadSw ENDP

WriteLd PROC

PUSH DX

PUSH AX

MOV AL,LdState

MOV DX,0E8E0H

OUT DX,AL

POP AX

POP DX

RET

WriteLd ENDP

excuteReturnToDos PROC

TEST SWSTATE,01H

JZ exitexcuteReturnToDos

CALL returnToDos

exitexcuteReturnToDos:RET

excuteReturnToDos ENDP

ReturnToDos PROC

MOV AX,4C00H

INT 21H

ReturnToDos ENDP

excuteDirection PROC

TEST SWSTATE,02H

JZ   shiftLeft

ROR  LDSTATE,01H

ROR  LDState,01H

shiftLeft:ROL LDSTATE,01H

exitexcuteDirection:RET

excuteDirection ENDP

excutePause PROC

beginexcutePause:CALL readSw

TEST swState,04H

JNZ beginexcutePause

RET

excutePause ENDP

excuteSpeed PROC

CALL divFreq

TEST swState,08H

JZ exitexcuteSpeed

CALL divFreq

CALL divFreq

exitexcuteSpeed: RET

excuteSpeed  ENDP

excuteMode PROC

PUSH WORD PTR ldState

TEST swState,10H

JZ simpleMode

PUSH AX

PUSH BX

PUSH CX

MOV AL,ldState

MOV BL,AL

ROL BL,1

AND BL,AL

MOV CL,BL

ROL CL,1

AND AL,CL

MOV ldState,AL

POP CX

POP BX

POP AX

simpleMode: CALL writeLD

exitexcuteMode: POP WORD PTR ldState

RET

excuteMode ENDP

Code ENDS

END Main

程序结构,伪代码

因为坑爹的实验要在DOS环境下敲代码,老师又各种催,所以注释没有加上。不过学长的变量和函数命名都相当清晰,相信大家一看就能懂。

程序以main为入口,跟一般高级语言编程是一个思路,太喜欢啦~

我就把程序的大致框架用伪代码写一下:

int main()

{

initialize();

while(1){

read_switch_state(); // Read the physical switches state.

execute_direction(); // Change the marquee direction according to the switches state read.

execute_mode(); // Change mode(Single/Triple Flashing) according to the switches state read.

execute_pause(); // Pause if the switches state acquires.

execute_return_to_dos(); // Return to DOS if the switches state acquires.

excute_speed(); // Delay. The latency is determined by the switches state read.

}

return 0;

}

类似函数的分块法

仔细品读了学长的代码,我又学会了汇编语言是怎样给程序分块的,也就是说写各种不同的“函数”,然后调用。

所有代码都在Code Segment里面写。“函数”(Process)是这样定义的:

(过程名) PROC

一些操作

RET

(过程名) ENDP

在“函数”(Process)的开始,一般会用栈保存寄存器的数据,操作结束的时候再恢复,这样函数就不会搞乱整个程序了。

汇编中使用变量

单靠寄存器,没有变量实在没法活呀。

哈哈,学长的代码就有“变量”的定义和使用方法,以后可以学着用。

留意到,代码里的变量都是直接定义在Data Segment,直接在程序里使用变量名就可以对变量进行读写等操作。

Data SEGMENT

SwState DB 0

LdState DB 0FEH

Buffer DB 0

Data ENDS

要注意的是,程序初始化的时候,一定要把DS指向Data Segment,否则变量是无法使用的!切记!

PUSH DS

XOR  AX,AX

PUSH AX

MOV AX,Data

MOV DS,AX

好啦,就写这么多啦,详情见代码吧。

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值