有这样一个问题:
-----------------------------
已知程序执行前有 A = 02H,SP = 52H,(51H) = FFH,(52H) = FFH。
执行下列程序:
POP DPH
POP DPL
MOV DPTR, #4000H
RL A
MOV B, A
MOVC A, @A + DPTR
PUSH A
MOV A, B
INC A
MOVC A, @A + DPTR
PUSH A
RET
ORG 4000H
DB 10H, 80H, 30H, 50H, 30H, 50H
求程序执行后:
A=( )H、SP=( )H、(51H) =( )H、(52H)=( )H、PC=( )H。
------------------------------
这个问题,在百度知道出现过很多次,搜一下,就会出来几十个链接。
但是回答正确的,确实不多。
有的提问者,好像是说,这是什么学校教材上的习题。
在这个程序中,写错了两条指令:
非法指令:PUSH A
应该写成:PUSH ACC
做为教材来说,这可是一个 BUG 啊,呵呵
这个程序,是利用 RET 指令来进行多路分支。
程序中,有两条查表指令:MOVC A, @A + DPTR,
当 A = 0 时,将从 4000H 处,先后读出 10H、80H;
当 A = 1 时,将从 4000H 处,先后读出 30H、50H;
当 A = 2 时,将从 4000H 处,先后读出 30H、50H。
本题目的条件已经给出:A = 02H,那么就是读出了 30H、50H。
读出数据后,先后压栈,再执行 RET。
RET 指令,就是把堆栈中的两个字节,送到 PC。
那么,PC = 5030H,就是这么来的。
全部的空格,填写如下:
A=(50)H、SP=(50)H、(51H) =(30)H、(52H)=(50)H、PC=(5030)H。
------------------------------
本程序,是个子程序结构,应该用 CALL 指令来调用。
在本程序开始处,用 POP 指令,抛弃了 CALL 自动保存的返回地址。
腾出了两个字节的堆栈空间,又压入两字节数据,然后,再返回。
RET 返回指令,就会用刚刚压入两字节数据,当做返回地址。
本程序,是属于偷梁换柱,还是移花接木 ?
------------------------------
下面逐条解释一下:
POP DPH
POP DPL ;弹出两次,SP = SP - 2 = 50H
MOV DPTR, #4000H
RL A ;乘以2
MOV B, A ;B = 04H
MOVC A, @A + DPTR ;取出第4个字节30H
PUSH ACC ;SP = SP + 1 = 51H, (51H)=30H
MOV A, B
INC A ;A = 05H
MOVC A, @A + DPTR ;取出第5个字节50H
PUSH ACC ;SP = SP + 1 = 52H, (52H)=50H
RET ;子程序返回指令
执行 RET 指令时,是从堆栈中弹出两个字节到 PC 的高、低八位。
即:
(SP) → PCH,然后 SP - 1 → SP;
(SP) → PCL,然后 SP - 1 → SP。
即:
(52H) = 50H → PCH,SP = 51H
(51H) = 30H → PCL,SP = 50H
那么,PC = 5030H,就是这么来的。
------------------------------
进行多路分支,还有简单一点的方法。
如,利用指令:JMP @A + DPTR,就可以。
那么,前面的程序,可以改为:
MOV DPTR, #4000H
RL A
MOV B, A
MOVC A, @A + DPTR
XCH A, B
INC A
MOVC A, @A + DPTR ;先后读出两字节
MOV DPH, A ;把读出数据送到 DPTR
MOV DPL, B
CLR A ;A=0
JMP @A + DPTR ;以 DPTR 内容为目的地,转移
ORG 4000H
DB 10H, 80H, 30H, 50H, 30H, 50H
程序这样写,就不涉及堆栈了,也就没有前一个程序那么复杂的推导。
理解起来,可以轻松些。
这个程序,没有使用 RET 指令,那么,就不要用 CALL 来调用了。
要用 JMP 指令来应用本程序。
上一篇:51单片机,点亮LED灯和闪烁
下一篇:51单片机 汇编语言电子琴
推荐阅读最新更新时间:2024-11-17 08:09
设计资源 培训 开发板 精华推荐
- LT1086CM-3.3 5V、1.5A 低压差正稳压器的典型应用
- STEVAL-MKI105V1,基于 LIS3DH 的适配器板,用于标准 DIL24 插座
- 使用 NXP Semiconductors 的 TDA3603 的参考设计
- 【创意PCB】中秋月饼拖尾流水灯
- LTC1550LIGN 1mVP-P 纹波、-2V 输出 GaAs FET 偏置发生器的典型应用电路
- F405-Wing-usb
- 示例工程_面板打印设计
- L7824C输出稳压电路的典型应用
- AD9245BCP-40EB,具有 AD9245 3V、14 位、40 MSPS ADC 的评估板
- 基于APM32和涂鸦智能的主从式环境监测显示器