单片机散转程序中ACALL和SJMP的键号必须乘以4才能得到正确的散转偏移量,为什么要乘以4??

来源:百度知道 编辑:UC知道 时间:2024/06/24 12:08:31
各位单片机高手帮帮忙,我在看单片机的书时,在汇编语言程序设计章节的散转程序设计模块看到这样一句话“ACALL和SJMP的键号必须乘以4才能得到正确的散转偏移量”,这是为什么啊?
还是有点不明白,下面是题,帮忙分析一下,谢谢了
“一单片机系统中设置了“+”“-”“*”“/”4个运算符,运算符的键值分别为0,1,2,3,假设键值已经读入到工作寄存器R7中。,要求根据键值号进行相应的运算。。。。。。
START:MOV P1.#0FFH ;置P1口为输入状态
MOV P2,#0FFH ;置P2为输入状态
MOV DPTR,#TABLE ;置“+、——、*、/”表首地址
CLR C
MOV A,R7
SUBB A,#04H
JNC ERROR ;键值不是0—3,转出错处理子程序
ADD A,#04H
RL A
RL A ;键号*4,得到正确的散转偏移号
JMP @A+DPTR ;散转
TABLE:ACALL PRADD ;转加法子程序
SJMP PREND ;转结束
.
.
.
.
ERROR:
.
.

乘以2是常见的,乘以3的也有;
乘以4,不像,请给出程序来分析一下。
---------------------
看明白了。
这书的作者,把各个程序的分支,写成了“调用子程序+转移指令”的形式,所以才有了如此“笨重”的散转方法。
且看它的分支表:
TABLE:
ACALL PRADD ;转加法子程序 从“TABLE +0”是第O个分支
SJMP PREND ;转结束

ACALL PRSUB ;转减法子程序 从“TABLE +4”是第一个分支
SJMP PREND ;转结束

ACALL PRMUL ;转乘法子程序 从“TABLE +8”是第二个分支
SJMP PREND ;转结束

ACALL PRDIV ;转除法子程序 从“TABLE +12”是第三个分支
SJMP PREND ;转结束

…… 从“TABLE +…………
……
它的每个分支,都是使用了两条2字节的指令,所以各分支,相差4个字节;如果要根据分支的号码,找到对应的地址,就应该乘以4。
这种4字节形式的分支表,所能容纳的分支数目,明显少于2字节的分支表。这种笨方法,也写成书,真是不可思议。

这个和程序里数据的存储方式有关:
阁下应该注意到:查表时数据存放时要写DB或者DW。
DB是双字节的意思,Dw是双字的意思,即四个字节。
如果前头写的是DW,每一个键号之间就相差4个字节,所以要乘4.