1楼:沙里波特
不是。
在单片机中,ret和reti分别是什么返回指令
2楼:匿名用户
在单片机中返回指令有ret、reti或者跳转指令sjmp或ljmp。
ret是一般子程序返回指令,执行该指令,会自动弹出被保护的地址给pc指针。
reti是中断服务程序返回指令,执行该指令,除了弹出被保护的地址指针给pc外,还会恢复影响中断的一些标志位,比如定时器中断的tfn标志。
3楼:东颖崇
ret是子程序返回
reti是中断返回,并且清中断标志,以保证能继续中断.
4楼:匿名用户
在单片机中分别是什么?返回指令?听听专业的人士了给你答复吧,我也不会的。
5楼:匿名用户
ret 是子程序的返回指令
reti 不清楚
单片机汇编语言指令中中断返回指令ret和reti有什么不同?
6楼:匿名用户
reti 是中断返回指令;
ret 是子程序返回指令;
reti比ret多一步清除中断优先级状态位,让同级别的中断有机会得到响应。
中断指令“reti”做为中断跳出指令除了将堆栈中保存着的地址取出,送回pc;使程序从主程序的中断处继续往下执行的作用外,还有将“优先级生效”触发器清零的功能。
7楼:做而论道
ret 是子程序返回指令。
reti 是中断服务程序返回指令。
两者,用途不同。
8楼:匿名用户
ret是子程序返回指令,返回到调用该子程序处的下一条指令执行,返回的地址是从ret执行前的sp中最后两个值。
reti是中断服务程序返回指令,返回到进入中断服务的断点处执行,返回的地址是从reti执行前的sp中最后两个值。
9楼:匿名用户
ret是普通子程序的返回指令,而不能用reti,所以,ret不是中断返回指令,就是子程序返回指令。
而reti是用在中断子程序的返回指令,必须用这个,这才叫中为返回指令,而不能用ret,这就是区别。
10楼:匿名用户
ret是子程序返回指令,将堆栈中的地址弹出,而reti是中断返回指令,除了将地址弹出,还将标志弹出
51单片机子程序中使用jmp(ajmp,ljmp,sjmp)指令 执行ret能不能回到主程序?
11楼:風間一葉
我仔细看了一下所有人的回答,有根本没看懂楼主问题答非所问的,也有回答的差不离的,我来切一下重点好了。
楼主这所有问题其实归根结底就是一个问题,堆栈和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的地址靠后那么就多点,不过一般够用是肯定的了
12楼:做而论道
jmp(ajmp,ljmp,sjmp)指令,是转移指令,它们在转移的时候,并不保留当前的地址,所以使用ret指令,是无法回到原来的位置的。
使用lcall、acall指令,就是调用子程序的指令,是可以用ret指令返回的,因为lcall、acall指令保存了原来的地址,可供ret使用。
另外,中断程序中是可以使用jmp指令的,但是要保证,要尽快使用reti返回原来的断点,否则就一直处于中断之中,cpu以后就不会再相应同级别的中断了。
------------------------
问题补充:
...,最后使用ret能不能回到call(acall,lcall)调用前的位置?
可以。...,多少次就会出错?
lcall、acall指令保存了原来的地址,是存放到堆栈里面。
51单片机的堆栈,是在片内ram中,空间是有限的。
空间究竟有多大,和你的栈底初始化的地址有关,另外,堆栈中,还会保存其它的内容。所以,保存返回地址的空间究竟能有多大,需要你自己计算。
多少次会出错,是和你编写的程序有关的。
你可以用keil软件来调试,把你的程序单步的运行走一遍,即可知道堆栈空间的使用情况了。
13楼:lixiao潇潇潇
在子程序内用跳转可以。但是如果在子程序内用跳转 跳出了这个子程序执行别的去了,这个就要小心了,你的ret没有执行(地址没有出栈),可能会出现数据的错误,如果后面反复调用该函数 也有可能因为地址只进栈不出栈 导致最终内存占满。
14楼:宇洁
我个人觉得你好像把这些指令的功能弄混了,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
retcall(acall,lcall)指令中调用call(acall,lcall),多少次就会出错?
这个问题我还没遇到过,一般在call中继续用call调用子程序不会出什么错误,除非你做的地址有重复,或者使用的寄存器有冲突,或者堆栈没有设计好,才会出错的,
我的回答基本就这些,这是第一次给别人回答,这些都是我自己的理解,因为我刚学的时候也遇到过类似的问题,不知道能不能对你有所帮助。
15楼:匿名用户
进入中断程序 后,执行reti,程序 转回进入中断子程序之前的位置。如果 用了jmp跳转走了,回不回到原处,很难说了。
16楼:张庚
汇编语言的这种跳转指令最直接了,跟着顺一遍就ok了一般是调用后,ret回主程序,这个的原理在于在call的时候,自动的把当前程序运行的位置存入堆栈,等于执行了一个push,ret的时候自动出站,把地址吐出来并跳到该位置
中断程序的reti和ret的不同在于它还涉及开关中断允许标志楼主自己可以推断一下,只要你jmp出去还在ret之前jmp回来,没有影响到该状态下的堆栈顺序就ok可以。这个常见的,当你的子程序或者中断程序里有判断分支的时候,常常会用判断性的跳转语句
单片机相对很接近硬件,只要把它各个指令执行的原理理清了,这个小东西怎么工作的,就可以灵活的利用汇编语言来控制了
17楼:匿名用户
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的说法只是象征性的概念,不代表具体指令,希望多你有所帮助。
18楼:骏驰飞车族
完全可以!
lcall covn
covn:mov a,31h
cjne a,#00h,next
ajmp out
next:mov 31h,#01h
out:ret
这个简单的子程序就是比较31h存储单元中的数值。如果等于就ajmp out,如果不等于就跳转到next处。只要是调用的子程序,然后跳转的范围是在子程序之内就,而且最后有ret或是中断的reti返回指令就行。
在我的某些程序中就会用到子程序中跳转的指令。完全正常!