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

还有就是中断程序中使用JMP(AJMP,LJMP,SJMP)指令,执行RETI能不能回到中断跳转前的程序位置.
请不要复制一堆不相干的东西来胡弄人..
CALL(ACALL,LCALL)调用中使用了JMP(AJMP,LJMP,SJMP)指令,最后使用RET能不能回到CALL(ACALL,LCALL)调用前的位置?
CALL(ACALL,LCALL)指令中调用CALL(ACALL,LCALL),多少次就会出错?

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

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

另外,中断程序中是可以使用JMP指令的,但是要保证,要尽快使用RETI返回原来的断点,否则就一直处于中断之中,CPU以后就不会再相应同级别的中断了。
------------------------
问题补充:
...,最后使用RET能不能回到CALL(ACALL,LCALL)调用前的位置?
可以。
...,多少次就会出错?
LCALL、ACALL指令保存了原来的地址,是存放到堆栈里面。
51单片机的堆栈,是在片内RAM中,空间是有限的。
空间究竟有多大,和你的栈底初始化的地址有关,另外,堆栈中,还会保存其它的内容。所以,保存返回地址的空间究竟能有多大,需要你自己计算。
多少次会出错,是和你编写的程序有关的。
你可以用keil软件来调试,把你的程序单步的运行走一遍,即可知道堆栈空间的使用情况了。
温馨提示:内容为网友见解,仅供参考
第1个回答  2010-04-06
我仔细看了一下所有人的回答,有根本没看懂楼主问题答非所问的,也有回答的差不离的,我来切一下重点好了。
楼主这所有问题其实归根结底就是一个问题,堆栈和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的地址靠后那么就多点,不过一般够用是肯定的了本回答被提问者采纳
第2个回答  2010-04-03
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的说法只是象征性的概念,不代表具体指令,希望多你有所帮助。
第3个回答  2010-04-03
我个人觉得你好像把这些指令的功能弄混了,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调用子程序不会出什么错误,除非你做的地址有重复,或者使用的寄存器有冲突,或者堆栈没有设计好,才会出错的,

我的回答基本就这些,这是第一次给别人回答,这些都是我自己的理解,因为我刚学的时候也遇到过类似的问题,不知道能不能对你有所帮助。
第4个回答  2010-03-31
汇编语言的这种跳转指令最直接了,跟着顺一遍就ok了

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

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

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

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

51单片机指令中sjmp的具体用法,详解???
sjmp 短距离跳转指令,可前跳127或后跳127字节, 指令共两个字节 多用于程序空间不够用和提高速度时 但要注意是跳转 点太远编译时就会报错 ajmp 中距离跳转指令,可前跳2K或后跳2K字节, 指令共两个字节 多用于程序空间不够用和提高速度 ljmp 长距离跳转指令,可前跳64K或后跳64K字节, ...

单片机中JMP与LJMP,SJMP,AJMP有什么区别
SJMP 如果跳转到的标号地址距离当前PC所指的地址小于256字节,用SJMP AJMP 如果跳转到的标号地址距离当前PC所指的地址小于2K字节,用AJMP LJMP 如果跳转到的标号地址距离当前PC所指的地址小于64K字节,用LJMP ACALL是你调用的子程序入口地址距离当前PC所指地址需介于0~2K,LCALL是0~64K。

51单片机做数字电子钟
源程序如下: ORG 0000H ;程序开始入口 LJMP START ORG 0003H ;外中断0中断程序入口 RETI ORG 000BH ;定时器T0中断程序入口 LJMP INTT0 ;跳至INTTO执行 ORG 0013H ;外中断1中断程序入口 RETI ORG 001BH ;定时器T1中断程序入口 LJMP INTT1 ORG 0023H ;串行中断程序入口地址 RETI ;---主...

单片机中sjmp和ljmp是啥意思啊
如果把单片机64KB寻址区分成32页(每页2KB),则PC15—PC11(00000B—11111B)称为页面地址(即:0页—31页),a10—a0称为页内地址,但应注意:AJMP指令的目标转移地址不是和AJMP指令地址在同一个2KB区域,而是应和AJMP指令取出后的PC地址(即:PC+2)在同一个2KB区域。例如:若AJMP指令地址为2...

单片机中的AJMP LJMP SJMP JMP有什么区别?
LJMP 如果跳转到的标号地址距离当前PC所指的地址小于64K字节,用LJMP。ACALL是调用的子程序入口地址距离当前PC所指地址需介于0~2K,LCALL是0~64K。2、跳转的范围不一样。AJMP 的范围是11位地址,也就是2K的空间内,占用存储空间2个字节,执行周期24个时钟周。LJMP 的范围是16位地址,也就是64K的空间...

AJMP相关指令
在51单片机中,有一种指令用于实现长距离的程序跳转,即LJMP指令。这种指令支持长跳转,可以在芯片的最大可编程内存区域,即ROM的64KB范围内进行操作,为程序员提供了更大的空间来设计复杂的程序流程。相比之下,SJMP指令则执行短距离的跳转,其范围限定在-128到+127个ROM单元之间。这意味着它适用于那些...

单片机汇编语言RET没有和ACALL配套使用时返回到哪里?
如不是在调用后RET了那就只会回到你堆栈最上高二地址(栈)中所指的地址上去了,你可这试试,先用二个压栈指令POP压二个数后(低位先压)再RET,这会程序就会转到你压的这个数的地方运行起走。一般书上的例程绝大多数是以子程序方式表示的,所以是只等你调用的。

LJMP、AJMP、SJMP指令的区别是什么?使用AJMP和SJMP指令有什么注意事项...
【答案】:一是转移范围不一样:LJMP转移范围是64KB;AJMP转移范围是与当前PC值同一2KB;SJMP转移范围是当前PC-128B~+127B。二是指令字节不一样:LJMP是3字节指令;AJMP、SJMP是2字节指令。使用AJMP和SJMP指令应注意转移目标地址是否在转移范围内,若超出范围,程序将出错。转移目标地址一般用转移目标的...

51单片机的所有指令
RET 22 子程序调用返回 RETI addr 11 32 中断调用返回 AJMP addr 11 △1 addr(a7~a6) 绝对转移 LJMP addr 16 02addr(15~8) 长转移 addr(7~0) SJMP rel 80 rel 短转移,相对转移 JMP @A+DPTR 73 相对于DPTR间接转移 JZ rel 60 rel A为零转移 JNZ rel 70 rel A为零转移 CJNE A,dircet,rel ...

单片机指令中长转移LJMP,短转移SJMP和绝对转移AJMP还有JMP到底有什么...
跳的距离不一样,SJMP,AJMP,LJMP就像立定跳、跑跳和三步跳,其实写程序时,只要写JMP就可以了,keil编译时让它自己做,我们不必理会它是具体哪一个。

相似回答