51 单片机汇编语言:利用 RET 指令实现多路分支
来源:互联网 发布:office mac版怎么安装 编辑:程序博客网 时间:2024/06/05 10:54
有这样一个问题:
------------------------------
已知程序执行前有 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 指令来应用本程序。
------------------------------
题目链接:
http://zhidao.baidu.com/question/62813244.html
http://zhidao.baidu.com/question/508425830.html
http://zhidao.baidu.com/question/586060870.html
http://zhidao.baidu.com/question/205965529.html
------------------------------
- 51 单片机汇编语言:利用 RET 指令实现多路分支
- 慎用51单片机中的RET指令
- 汇编语言教程-返回指令(RET)
- 汇编语言--call和ret指令
- 8086汇编语言 ret指令实例
- 汇编语言笔记10-CALL和RET指令
- 单片机汇编语言指令
- 51单片机 ret和reti
- <学习笔记>王爽汇编语言__CALL和RET指令
- 汇编语言09——Call和Ret指令
- 【汇编语言/底层开发】10、CALL和RET指令
- 汇编语言 call和ret指令 的具体执行
- 汇编语言学习第十章-CALL和RET指令
- 关于汇编语言中RET指令无法回到正确位置
- 王爽 《汇编语言》 读书笔记 十 CALL和RET指令
- 单片机汇编指令中RETI和RET的区别
- 单片机汇编指令中RETI和RET的区别
- RET指令
- Vmw11上安装完OS X 10.9之后升级为10.10的注意点
- 寒風的Cocos之旅之Lua篇---2048移动块的机制
- 80x86 汇编语言:去掉1个最高分,去掉一个最低分,再取平均
- 用 51 单片机和 DAC0832 做波形发生器
- 几何题:在三角形ABC中,AD 垂直于...
- 51 单片机汇编语言:利用 RET 指令实现多路分支
- xp中搭建php环境(安装php并配置)
- 80x86汇编语言编程:相邻两字符的判断
- C 语言编程:输入 16 进制,以 8 进制输出
- 51 单片机 C 语言:不规则的矩阵键盘
- 80x86 汇编语言编程:编程实现 sum=1+2+…+100
- C 语言编程:输入10个整数,将其中最小的数与第一个数对换
- C 程序:号码验证方法
- Java读取文件夹大小的6种方法及代码