中华学习机原理和应用(14) 汇编语言程序设计

🏠 首页 《无线电》杂志 1989年 🔗 第2期 🔗 第28页 分类:技术市场 🔗 黄金明 🔗, 乌振声 🔗

一、分支程序

(乌振声 黄金明)在程序设计中,经常会遇到各种判断和比较,如“相等”和“不相等”;“大于”和“小于”;“满足条件”和“不满足条件”等等。这些判断和比较在程序中都可以组成各种不同的逻辑框,并产生相应的分支程序,根据不同条件可以使程序转向不同的分支。所以。一般一个程序都不会是一直执行下去的一个模块的结构,而是有许多条件判断的多模块结构。

例如符号函数就是一个例子:

图1
图1 🔍原图 (304×139)

下面我们用65SC02的汇编指令来实现符号函数。假设自变量X的值已存入标号为VAL的单元中,求出的函数值放在标号为RES的单元中,X(-128≤X≤+127)为带符号的8位二进制数。用条件转移指令即可按标志位的情况,实现程序的分支。程序框图如图1所示,程序如下:

图2
图2 🔍原图 (500×649)

START LDA VAL ;X→A

CMP #$OO ;查X的特点

BEQ ZERO ;X=0

BMI MINUS ;X<0

LDA #$1 ;X>Q,则1→A

JMP ASSIGN

ZERO LDA #$00 ;X=0,则

JMP ASSIGN

MINUS LDA #$-1 ;X<0,则-1→A

ASSIGN STA RES ;A→Y

END

二、循环程序

前面介绍的分支程序根据条件的不同,跳过一些指令转而执行另一些指令,最多也只能执行一次。在某些情况下,程序中的某一段程序要反复执行多次,这段反复被执行多次的程序环称之为循环程序。循程序使程序长度大大缩短,所以,凡能使用循环程序的地方应尽量采用它。

循环程序一般由四部分组成:①、初始化部分:分为循环工作部分的初始化和结束条件的初始化。②、处理部分:它进行数据处理和操作。③、循环控制部分:用来判断循环结束的条件。④、结束部分:循环程序的构成如图2所示。必须注意:不要使循环返回至初始化部分,否则会导致死循环,这是初学者常出的错误。

图3
图3 🔍原图 (386×426)

[例]将存放在2000—20FF单元中的256个数据送到3000—30FF单元中去。

由于每一次传送数据的指令的操作码都是一样的,只是每一次传送数据的源地址和目的地址不一样。这样,用X寄存器的零页变址方式,把源地址和目的地址放在零页单元中,然后用加1的指令来修改源地址和目的地址,则传送指令对任何一次传送都是一样的。这样可以循环使用传送指令。本题程序框图如图3所示。

图4
图4 🔍原图 (561×861)

源程序:

ORG

DFB $00,$20 ;源数据块首地址填入;1A,1B单元

ORG

DFB $00,$30 ;目的块首地址填入FA,FB单元

ORGC $1000 ;源程序起始地址

START LDX #OO ;0→变址寄存器X

LDY #$FF ;数据块长度→Y

MOVE LDA($1A,X);传送一个源数据

STA($FA,X);到目的地址单元中

INC $1A,X 修改源地址,使之加1

INC $FA,X ;修改目的地址,使之加1

DEY ;数据块长度-1→Y

BNE MOVE ;数据未传送完,继续循环传送

BRK;结束

三、子程序

在程序编写过程中,经常会遇到相同的计算或操作。例如,作乘法、除法、求平方根、三角函数等,如果每次都从头开始编写计算程序,不仅麻烦而且是一种浪费。所以,把这些相同的部分编写成一个独立的程序段,称之为子程序。当遇到相同的计算或操作时就调用子程序,而不必对这些相同部分重复编写程序了。通常情况下,整个程序是由主程序和几个子程序组成的。65SC02微处理机备有专门的转子指令JSR,用以把控制转移到子程序。还备有专门的子程序返回指令RTS,用以使子程序返回到主程序。主,子程序关系如图4所示。

图5
图5 🔍原图 (657×294)

在存储器M4地址中,存放着一条转子指令JSR ROUT,当主程序执行到地址M4中的转子指令时,要求如下:

1.将主程序的断点地址M5压入堆栈,并把子程序ROUT的起始地址送入程序计数器PC,实现向子程序的转移。

2.在子程序的最后一条指令必须是RTS返回指令,它能使主程序的断点地址M5从堆栈中退出送入程序计数器PC,从而使主程序能继续往下执行。

[例]在16个不带符号的二进制数据中找最大值。数据在放在2000—200F之间的单元中,求得的最大值存入06单元。

图6
图6 🔍原图 (812×822)

在这个例子中,把两个数之间的比较单独编成一个子程序。子程序的功能就是把两个数中较大的数存入A寄存器。A寄存器中总是存放着已比较过的数据中的最大值。通过Y寄存器每次加1,即可实现存放数据的内存地址加1,又可兼作数据块的长度计数。由于共有16个数据要进行比较,所以,主程序需要调用子程序16次,才能找出最大值。程序框图如图5所示。

程序如下:

ORG $1000

START LDA #00 ;数据块首址送08和07单元

STA $07 ;即(08)(07)=$2000

LPA #$20

STA $08

LDY #00 ;置计数器Y初值=0

LDA #00 ;设最大值为0放在A中

LOOP JSR MAXM

INY ;计数器+1

CPY #$10 ;计数器中的值=16?

BNE LOOP ;不等于数据块长度、继续比较

STA $06 ;最大值送06单元

BRK ;结束

MAXM CMP($07),Y ;下一个数>最大值?

BCS NOCHG ;不大于时,最大值保持不变

LDA($07),Y;大于时,换最大值存入A中

NOCHG RTS ;返回主程序

四、程序举例

在显示器屏幕的顶端显示“PLEASE TYPE LETTERA”一串字符。然后从键盘输入字母A,则在下一行继续显示“PLEASE TYPE LETTER A”字符串。

在这个例子中,需要调用监控程序中的几个子程序,下面先把监控程序中的几个子程序入口地址介绍一下。

$FC58:清屏幕子程序

$FE89:设定键盘为输入设备子程序

$FE93:设定CRT为输出设备子程序

$FDFO:输出一个字符到CRT子程序

$FD35:从输入设备读一个字符子程序

程序如下:

ORG $1000

START JSR $FC58

JSR $FE89

JSR $FE93

LOOP LDY # $00

LDA DISAD,Y

STA $05

INY

LDA DISAD,Y

STA $04

DIS1 LDY # $00

LDA ($04),Y;

CMP #$00

BEQ RD1

JSR $FDFO;

JSR CAL

JMP DIS1

RD1 JSR $FD35

CMP #$C1

BNE RD1

JMP LOOP

CAL CLC

LDA $04

ADC #$01

STA $O4

LDA $05

ADC #$00

STA $05

RTS

DISAD DBY DISPLAY

DISPLAY BYT $8D,

ASC“PLEASE-TYPE-LET-TERA”

BYT $6A,$00

END