51单片机子程序中使用JMP(AJMP,LJMP,SJMP)指令 执行RET能不能回到主程序?

作者&投稿:梅帖 (若有异议请与网页底部的电邮联系)
单片机能否使用LJMP指令从主程序转入子程序或从子程序跳回主程序,为什么?~

这个当然是能使用LJMP指令重主程序跳转到子程序,或从子程序跳回主程序,但一般是不允许这样使用LJMP指令的,很容易造成程序运行混乱。因为调用子程序保护现场要将当前的地址压入堆栈,子程序返回时,会弹出该地址赋值给PC指针。如果使用,必须满足以下条件:
1、跳出跳入成对出现,也就是说,从主程序用LJMP跳转到子程序,那么在子程序中的RET前,必须是用LJMP指令跳回。
2、不成对出现,但是如果子程序是LJMP跳转来的控制,那么在RET前,需要压入返回位置的地址。比如:
主程序:
.....
LJMP  SUB01
 ........
CON: ;返回地址
......
SUB: ;子程序
....
SUB01: ;跳转到的地址
....
MOV DPTR,#CON ;返回前处理。
PUSH DPH
PUSH DPL
RET

调用函数 就必须用 xCALL指令此时把下条指令的地址压入栈,那么返回就必须是ret指令,指令出栈,如果你不用RET 用JMP当然也行,但是会影响栈堆
但是不建议这样。

JMP(AJMP,LJMP,SJMP)指令,是转移指令,它们在转移的时候,并不保留当前的地址,所以使用RET指令,是无法回到原来的位置的。

使用LCALL、ACALL指令,就是调用子程序的指令,是可以用RET指令返回的,因为LCALL、ACALL指令保存了原来的地址,可供RET使用。

另外,中断程序中是可以使用JMP指令的,但是要保证,要尽快使用RETI返回原来的断点,否则就一直处于中断之中,CPU以后就不会再相应同级别的中断了。
------------------------
问题补充:
...,最后使用RET能不能回到CALL(ACALL,LCALL)调用前的位置?
可以。
...,多少次就会出错?
LCALL、ACALL指令保存了原来的地址,是存放到堆栈里面。
51单片机的堆栈,是在片内RAM中,空间是有限的。
空间究竟有多大,和你的栈底初始化的地址有关,另外,堆栈中,还会保存其它的内容。所以,保存返回地址的空间究竟能有多大,需要你自己计算。
多少次会出错,是和你编写的程序有关的。
你可以用keil软件来调试,把你的程序单步的运行走一遍,即可知道堆栈空间的使用情况了。

我仔细看了一下所有人的回答,有根本没看懂楼主问题答非所问的,也有回答的差不离的,我来切一下重点好了。
楼主这所有问题其实归根结底就是一个问题,堆栈和SP(堆栈指针)的问题
CALL指令执行时,就是先把当前程序指针压入堆栈并使SP加1,然后开始执行CALL指令调用的子程序,当遇到RET指令时,把前面压入堆栈的程序指针取出并SP减1(出栈),然后就回到CALL程序调用前位置了。
JMP指令并不会把程序指针压入堆栈更不会影响SP(当然自己在JMP后用PUSH指令除外)。自然CALL调用后使用JMP指令跳转,最后遇到RET指令一样能回到CALL程序调用前位置。就算你在JMP指令后使用PUSH指令,只要和POP成对出现,还是会回到调用前的位置,不成对?这堆栈不能这么用的。。飞了。。飞了。
中断其实和CALL指令时一样的道理,至于用RETI就如张庚(3楼)兄弟说的中断是要多处理一些标志位。
至于调用CALL多少次出错,这还是堆栈和SP的问题。
如我上面所写,CALL指令一次就得压栈一次,而你在RET指令前又来一次CALL指令,那么还得压一次,这样一直下去堆栈指针愈来愈大,就会占用程序所要使用的RAM地址,自然肯定会出错,一半51单片机默认SP为07H,而一般编程RAM地址20H开始就会被程序占用,一算就知道了,大概10几20次吧,如果你中间还是用堆栈那么就少点,如果你的程序占用RAM的地址靠后那么就多点,不过一般够用是肯定的了

JMP是跳转指令,只要在合法范围内随便用,跟RET和CALL指令没多大关系,
RET和CALL才是一对,当使用CALL指令调用一个函数并把程序指针SP入栈记录当前执行位置,比如说循环延时程序时,程序转去执行子程序,程序执行到RET指令时出栈SP,返回程序执行原位置。

至于JMP指令能不能用RET返回,应该是不能的,JMP只是跳转不是调用,当执行JMP命令的时候CPU修改程序指针SP为跳转地址。他和RET指令没关系。

RETI命令和RET命令作用差不多,当CPU响应中断后,转去执行中断函数,中断函数执行到RETI命令时指示CPU中断函数结束,程序返回原位置执行,RETI与RET的区别就是前者用于中断函数的返回,后者用于一般函数的返回。

至于CALL指令执行多少次会出错,根据CPU架构不同这个有所不同,具体芯片应该可以在芯片手册里面查到。

以上JMP和CALL的说法只是象征性的概念,不代表具体指令,希望多你有所帮助。

我个人觉得你好像把这些指令的功能弄混了,JMP(AJMP,LJMP,SJMP)指令这些指令时单纯的跳转指令,比如JMP loop 这条指令,就是程序跳转到LOOP这个地方去执行,并没有什么返回不返回的说法,除非执行过程中遇到别的指令。这几个指令的区别的跳转的距离,有短跳转,长跳转,这些你去看看指令表应该就知道了。
至于ret 是专门给子程序调用的时候用的,当你调用一个子程序,子程序执行完之后,必须要写一个ret 这个指令,用来返回你调用子程序的那句程序的位置,以便程序继续运行。
而RETI 是专门给中断子程序使用的,是用来做中断返回用的。
这两个指令跟JMP没有关系,使用的时候在子程序里依然可以使用JMP,但需要注意的是你用完JMP就不会返回到原来的地方,所以一般在子程序使用JMP不会超出本子程序的范围,否则可能会造成程序跑飞,乱套了。
CALL(ACALL,LCALL)调用中使用了JMP(AJMP,LJMP,SJMP)指令,最后使用RET能不能回到. 这个问题跟我刚才说的一样。

CALL(ACALL,LCALL)调用前的位置?
这个给你举例说吧:
.....
mov a,#00h
call loop ;这里就是call调用之前的位置
mov r1,#21h ;这里是call调用之后返回的位置
......
loop:
jc c
mov a,#01h
ret

CALL(ACALL,LCALL)指令中调用CALL(ACALL,LCALL),多少次就会出错?
这个问题我还没遇到过,一般在call中继续用call调用子程序不会出什么错误,除非你做的地址有重复,或者使用的寄存器有冲突,或者堆栈没有设计好,才会出错的,

我的回答基本就这些,这是第一次给别人回答,这些都是我自己的理解,因为我刚学的时候也遇到过类似的问题,不知道能不能对你有所帮助。

汇编语言的这种跳转指令最直接了,跟着顺一遍就ok了

一般是调用后,ret回主程序,这个的原理在于在call的时候,自动的把当前程序运行的位置存入堆栈,等于执行了一个PUSH,ret的时候自动出站,把地址吐出来并跳到该位置

中断程序的reti和ret的不同在于它还涉及开关中断允许标志

楼主自己可以推断一下,只要你JMP出去还在ret之前JMP回来,没有影响到该状态下的堆栈顺序就ok可以。这个常见的,当你的子程序或者中断程序里有判断分支的时候,常常会用判断性的跳转语句

单片机相对很接近硬件,只要把它各个指令执行的原理理清了,这个小东西怎么工作的,就可以灵活的利用汇编语言来控制了


单片机中,我的两个子程序中都有死循环。如何编写使得按按键可以从这_百...
程序构架:主函数→调用子函数1→退出子函数1,返回主函数→调用子函数2→退出子函数2,返回主函数。看懂没,程序不能卡死在子函数里面,必须是循环执行各个子函数。作为子函数,你可以不动作,但不能占着茅坑不拉屎!

在单片机中子程序与中断服务程序的异同点。
差别:⑴中断请求信号可以由外部设备发出,是随机的;子程序调用却是由软件编排好的。⑵中断响应后由固定的矢量地址转入中断服务程序,而子程序地址由软件设定。⑶中断响应是受控的,其响应时间会受一些因素影响;子程序响应时间是固定的。中断 #子程序 #硬件 #软件 ...

单片机中这个子程序实现什么功能
这个AD转换程序,可能是MCP3202的驱动程序

帮忙解释一段单片机程序
这是一个令单片机P0.0脚输出信号不断翻转(高电平,低电平)的程序.高低电平持续时间由延迟子程序DEL决定,DEL子程序中的R5,R6,R7三个寄存器中的值控制着延迟时间,=== MAIN: MOV P0,#0FEH ;P0.0低电平 ACALL DEL MOV P0,#0FFH ;P0.0高电平 ACALL DEL AJMP MAIN === DEL中的R5,R6,R...

MSP430单片机中,如何设置中断子程序,可以使系统从LPM4 模式进入活动...
在主函数中进入休眠模式并打开总中断,然后在中断程序里面执行想要的操作就可以了。一般XT2IN的频率为高频,按实际应用时的要求来选用;XIN为低频,可以是32 768Hz。XIN的用途主要是在低功耗时使系统保持“活着”。MSP430共有5种省电方式,即LPM0~4。系统在LPMO-3方式下可以被唤醒,LPM4则不能。大...

单片机中延时子程序的作用是什么
就是为了延时啊,譬如说你让数码管从1变到10,一秒跳一下这就需要用到延时啊当然你可能会说用定时器就行了,但是定时器有限,而且他是通过中断来控制,但我不需要延时时间那么精准的时候用起中断就不够直接用延时程序方便了

单片机中,如何使用计时器1来产生PWM波形。主要是和计时器0的区别。谢...
typedef unsigned char uint8;typedef unsigned int uint16;typedef long unsigned int uint32;uint16 time0;uint16 PULSE_WIDTH = 0x300; \/\/脉冲宽 uint8 DUTY_CYCLE = PULSE_WIDTH*(1\/5);\/\/占空比 \/\/\/延时子程序 void delay(uint8 ms){ uint8 i;while(ms--){ for(i=0;i<120;...

51单片机编程子程序声明中的参数可以随便写
这是你的编译系统的容错性问题.红箭头指的实际上是定义语句,08,10行才是调用delay子程语句,这2行里的数就是数值了.

51单片机 定时器中断子程序中的累加数能在主函数中清零吗
当按下键K后只能一次有效,否则就会由于按下键到松开的时间相对与单片机而言是很长的,在此期间不断地清0,所以,结果就是恒为0了。这样改就行了:if(k==0){ w=c;c=0;\/\/若再辞清零,则c恒为0,若置1000,则恒为1000 while(k==0); \/\/在此等待按键释放,就会实现按键一次有效,必须...

单片机延时子程序
太夸张了,居然要20秒延时。真的太夸张。20秒何等概念。涉及长时间的系统不如加个时间芯片吧!按照你的晶振12M给你算的,不知道准不准.你试下。豪秒延时 void DelayMs(int delayms){ int i;while(delayms--){ for(i=0;i<48;i++){ _nop_();} } } 秒延时 你要20 秒,参数为20就可以...

彭阳县15015866685: 51单片机子程序中使用JMP(AJMP,LJMP,SJMP)指令 执行RET能不能回到主程序? -
阎仪香砂: 我仔细看了一下所有人的回答,有根本没看懂楼主问题答非所问的,也有回答的差不离的,我来切一下重点好了. 楼主这所有问题其实归根结底就是一个问题,堆栈和SP(堆栈指针)的问题 CALL指令执行时,就是先把当前程序指针压入堆栈...

彭阳县15015866685: 单片机中的AJMP LJMP SJMP JMP有什么区别? -
阎仪香砂: 个人觉得最好用的是LJMP,因为它是长转移,所以无论程序在何处,都可以跳到你要的地方,同样LCALL也是非常好用,它是长调用子程序,也是无论程序执行到何处,遇到它都可以调内存里任何一个位置子程序 所以我用最简单的一句话告诉你,在你需要跳转的时候就用LJMP,在你需要调程序的时候就用LCALL

彭阳县15015866685: 单片机中sjmp和ljmp是啥意思啊 -
阎仪香砂: MCS-51的控制转移类指令,共17条,分为无条件转移指令、条件转移指令、子程序调用和返回指令、空操作指令等四类.无条件转移指令(共4条) LJMP addr16 ; PC〈—— addr16 AJMP addr11 ; PC〈—— PC+2 , PC10-0〈—— addr11 ...

彭阳县15015866685: 关于51单片机中的CALL与JMP指令 -
阎仪香砂: 可能编译器会根据偏移量自动用LCALL或者ACALL代替CALL指令,JMP 标号也类似,你可以看看反汇编的结果,对比一下

彭阳县15015866685: 单片机里汇编编程子程序中能无条件转移到主程序执行么?还是不能用JMP... -
阎仪香砂: 调用函数 就必须用 xCALL指令此时把下条指令的地址压入栈,那么返回就必须是ret指令,指令出栈,如果你不用RET 用JMP当然也行,但是会影响栈堆 但是不建议这样.

彭阳县15015866685: 单片机jmp@a dptr用于什么结构的程序设计 -
阎仪香砂: 是jmp @a+dptr吧,用于51单片机中间接跳转,一般用于多个函数组合受某参数不同而发生调用的情况,类似于C语言的switch结构.

彭阳县15015866685: 单片机的子程序(子程序和中断服务子程序)中是不是最后不能用LJMP之类的跳转指令的?只能是RET或 -
阎仪香砂: CALL 和 RET ,这两条指令,要配套使用.JMP 和 RETI,不属于它们,不可滥用.

彭阳县15015866685: 问下单片机怎么调用子程序? -
阎仪香砂: ORG 0000H LJMP START ORG 000BH LJMP INT_T0 START:SETB EA SETB ET0 MOV TMOD,#01H MOV TH0,#3CH;定时50ms MOV TL0,#0B0H SETB TR0 MOV R2,#20;循环20次1s SJMP $ INT_T0:MOV TH0,#3CH MOV TL0,#0B0H DJNZ R2,RETURN CPL P1.1;够1s取反 MOV R2,#20;重新设置循环次数 RETURN:RETI 这可是本人辛辛苦苦给你现写的!!!!

彭阳县15015866685: 单片机中JMP与LJMP,SJMP,AJMP有什么区别 -
阎仪香砂: 跳转距离不一样,指令长度不一样

彭阳县15015866685: 51单片机汇编 -
阎仪香砂: 51单片机汇编中的反汇编其中JMP代码不太明白 如 JMP START 反汇编为 80F6 SJMP START(C:0000) 为啥是F6而不是00 --怎么会是 00 呢?我看了所有涉及到JMP指令的都不是制定的地址而是一个不知道是啥的代码 另外反汇编中头一列地址前边的“C:”是什么意思 --51 单片机的程序存储器称为:code.

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网