CASL语言程序编制度量精解
根据考试大纲的桪,高级程序员级应熟练掌握面向对象编程技术,熟练使用C/C++语言编制程序,能使用CASL汇编语言编制程序,具有良好的编程风格和较强的算法设计能力。程序编制能力由下午度量考查,共有3道题,其中CASL汇编语言试题1道,C语言程序试题2道,试题形式都是根据给定的算法和不完整的程序,填补空缺的语句。从1999年开始,不再选考Fortran语言,本书也就不收录Fortran语言试题,以前的Cobol
、Pascal试题也没有收录。
CASL汇编语言是从许多具体机型的汇编语言中抽象出来的一种简化的、专用于考试的汇编语言。如果没有接触过,需要下点功夫来学习和练习,基本语法请参见本书的附录三。为便于考生复习CASL,附录四收录了程序员级考试的试题。
试题1 (2000年试题4)
在COMEF型计算机上可以使用试卷上所附的CASL汇编语言。程序说明和CASL程序,将应填入(n)
处的字句,写在答卷的对应栏内。
[程序1说明]
1.
本子程序根据每位职工的基本工资(非负值)和他完成产品的超额数或不足数计算职工的应发工资。
2. 主程序调用时,CRI中给出子程序所需参数的起始地址,参数的存放次序如下表。
GR1
|
a1 |
|
b1 |
|
c1 |
|
a2 |
|
b2 |
|
c2 |
|
… |
|
an |
|
bn |
|
cn |
|
-1(结束标志) |
其中为职工的基本工资,为职工的完成产品的超额数或不足数,为职工的应发工资数(i=1,2,…,n)。
bi以原码形式存放(大于零为超额,小于零为不足)。基本工资与计算所得的应发工资以补码形式存放。
3.应发工资的计算规则为:
·恰好完成定额数(此时为零),应发工资即为基本工资。
·每超额4件,在基本工资基础上增加10元(不到4件,以4计算。例如超额数为10时,增加30元)。
·每不足4件,在基本工资基础上减5元(不到4个,以4计算。例如,不足数为5时,减10元)。
[程序1]
|
|
START |
|
BEG |
PUSH 0,GR1
PUSH 0,GR1
PUSH 0.GR2
PUSH 0.GR3
(1)
JEA GR0,0,GR2
JMI FINISH
LD GR3,3,GR1
LEA GR2,0,GR3
AND GR2,C7FFF
JZE L3
SRL GR3,15
LEA GR2.-1,GR2
(2)
LEA GR2,-4,GR2
JPZ L2
(3)
(4)
(5)
POP GR3
POP GR2
POP GR1
RET
DC #7FFF
DC 10
DC -5
END |
|
|
|
L1 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
L2 |
|
|
|
|
|
L3 |
|
|
|
|
|
FINISH |
|
|
|
|
|
|
|
7FFF |
|
BONUS |
|
|
|
|
|
|
[解析]
阅读程序说明,特别要注意在GRI中给出的子程序所需要的参数。可以看出,有所给参数中包含4类数据:1、ai,
,职工i的基本工资;2、bi ,职工i的完成听超额数或不足数;3、ci,职工i的应发工资;4、-1,结束标志。
在阅读程序说明的其他部分以后,开始阅读程序。从程序开始到第4行是子程序的起始部分,执行保存现场的操作,将GR1、GR2、GR3的内容分别入栈,这一部分是容易理解的,而且也与本题的解答关系不大。
第5行需要填写内容,但现在程序刚刚开始,我们很难从已知的信息推断出这里应该填写的内容。那么就跳过第5行继续阅读程序。第6行的语句给我们很多想像。在这里将GR2的内容取到GR0中去了。注意,子程序开始时,只有GR1的内容对子程序是有用的,GR2的内容是由调用子程序时主程序的运行善的。如果第5行不是对GR2进行操作,将某数据装入GR2,第6行的操作将导致无法预测的结果,尤其时在第7行有一个JMI语句。这样,我们就可以判断第5行的大体内容。即在GR2中装入某个有用的数据。倡这里装入的是什么数据呢:仍旧需要结合后面的语句进行解答。
第7行的"JMI FINISH
"可能导致程序的结束,问题是什么时候程序可能结束。程序当然是在遇到结束标志时结束,但在程序的开始部分就如此安排显然时不妥当的,我们再考察数据的存储。可能出现负数的只有结束标志和两类,显然遇到数额不足的职工就退出程序也是不妥当的。仍旧要从结束标志上看。现在让我们来假设,如果此处装入GR2的内容是GRI所指地址的内容,那么在处理完一个职工的工资后将GRI内容后跳3个字节,在处理完 了所有职工后,GR1所指地址的内容巍然是结束标志。暂且作这样的假设,在填空(1)中填写"LD GR2,0,GR1"。
继续阅读程序。第8行的语句告诉我们将某位职工的超额数或不足数装入GR3,然后在第9行中又把GR3的内容拷贝到GR2中。第10行的AND操作究竟有什么作用?如果我们注意到是以原码方式存储的,而且注意到数据C7FF的特点,就不难判断这是取超额数或不足数的绝对值。当绝对值为0时就跳转到第17行的L3。那么,从第17行起,必定有一个存储工资额的操作,因为在超额数或不足数为0时,应发工资即为基本工资。
接着阅读第12行。第12行的逻辑右移操作是简单的,可是目的难以判断。暂且在草稿纸上演示一番。当GR3是超额数时,经过右移,GR3的内容就变成0;当GR3是不足数时,经过右移,GR3的内容就变成1。这1和0怎样表示是超额数还是不足数呢?先跳过再说。第13行的操作更让人摸不着头脑,为什么把数额给减了一个去,我们也暂时存疑吧。
第14行是需要填写内容的,从下面的将GR2内容减4看,这里是将超额数或不足数的绝对值减了4,结合后面的"JPZ L2",第14行的语句应该是将奖金或罚款与基础工资进行加减操作的语句。考察变量BONUS定义,如果直接引用该变量,那么它就是10,如果引用该变量的下一个存储单元,就是-5。让我们再次提起第12行的逻辑右移。很、明显,如果我们这里使用GR3的内容来处理奖金或罚款,应该是很方便的。比如说,在这里填写"ADD GR0,BONUS,GR3",这样,当GR3内容为0(数额为超额数)时,这里回到GR0中的就是10,当GR3内容为1时(数额为不足数)时,这里加到GR0中的就是-5。再仔细阅读从第12行到第16行的语句,这样的实现是能够满足需要的。
现在看第16行,JPZ操作是在等于或大于时跳转。我们在这里可以举一个例子,当超额数为4时,第一次执行第14、15行时就完成了对应发工资的计算和对超额数进行减4操作,接着执行第16行,不免要跳转到第14行再进行一次奖金发放和超额数减4,然后才能够执行第17行的操作。显然这是不符合道理的。结合第13行考虑,上述的错误就不会发生了,具体过程学员可以自己计算。
关于第17行的内容,在前面我们已经判断为存储应发工资额了。现在关键是看如何实现,由于是要写到某个内存地址,所以必须使用ST。结合以上程序,可以知道应发工资额存储在GR0中,那么这里的第一个操作数就是GR0了。如何定位地址?程序中始终使用GR1来指示内存地址,这里最好不要例外,而且要想用别的寄存器指示内存地址还需要额外的操作,在这里是不允许的,所以我们就这样构造答案:"ST
GR0,1,GR1"
在第18、19行是在处理完一个职工的信息之后的操作,这里应该是什么操作?显然,应该是将GR1的内容加3,为下一个职工的信息处理提供正确的内存地址信息,然后再强制跳转到L1处。
在本题的答案中,我们应注意两点,一是始终注意寄存器内容的变化,二是始终注意变量的灵活使用。注意寄存器内容的变化,不仅要求掌握寄存器的内容发生了哪些变化,而且要求对寄存器在某种情况下应该如何变化有清醒的把握。对变量的灵活使用也包括两个方面,一是明确变量使用后发生的效果,其次是如何对连续存储的变量进行操作。
[答案]
(1)LD
GR2,0,GR1
(2)ADD
GR0,BONUS,GR3
(3)ST
GR0,2,GR1
(4)LEA
GR1,3,GR1
(5)JMP
L1
|