BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / circuit / #13848同步于 2010/5/31
Circuit机器人发帖

[合集] 51汇编的子程序位置问题

teamo
2010/5/31镜像同步0 回复
☆─────────────────────────────────────☆ katyusza (ka) 于 (Sat Aug 29 14:41:36 2009) 提到: 初学8051单片机, 调汇编程序的时候发现子程序的位置对运行结果有影响, 如下(1)和(2)所示。 翻书没找到相关说明, 猜测是汇编语言的子程序都应放在程序末尾, 我这理解对不? (1)子程序的“程序体”放在主程序的中间, 如下,这种方式下,程序运行不正常; main: 主程序段1 call sub sub: .... ret 主程序段2 end (2)子程序的“程序体”放在全部代码的末尾: 如下,这种方式,工作正常。 main: 主程序段1 call sub 主程序段2 sub: ... ret end ☆─────────────────────────────────────☆ phone (寒江钓叟) 于 (Sat Aug 29 18:04:33 2009) 提到: 问前面那个字用得简直传神极了 ☆─────────────────────────────────────☆ katyusza (ka) 于 (Sat Aug 29 19:30:28 2009) 提到: 谁也不是生下来就懂汇编语言嘛-_____________-!!! 【 在 phone (寒江钓叟) 的大作中提到: 】 : 问前面那个字用得简直传神极了 ☆─────────────────────────────────────☆ cyenux (cyenux) 于 (Sun Aug 30 22:11:25 2009) 提到: 代码执行过程一样,只是写入ROM地址不一样而已吧~ ☆─────────────────────────────────────☆ phone (寒江钓叟) 于 (Mon Aug 31 00:52:23 2009) 提到: 竟然和我猜想的一样。。。 【 在 cyenux 的大作中提到: 】 : 代码执行过程一样,只是写入ROM地址不一样而已吧~ ☆─────────────────────────────────────☆ katyusza (ka) 于 (Mon Aug 31 10:02:22 2009) 提到: 我的猜测是如果子程序放在中间, 那么执行到它的时候不管有没有call它它都会执行-_- 但是如果放在末尾, 那么主程序是一个连贯的整体, 在主程序段的末尾放个死循环之类的主程序就能连续执行、不会跳进子程序里面去了。 哎呀说的比较乱。。 【 在 cyenux (cyenux) 的大作中提到: 】 : 代码执行过程一样,只是写入ROM地址不一样而已吧~ ☆─────────────────────────────────────☆ cyenux (cyenux) 于 (Mon Aug 31 21:38:43 2009) 提到: 【 在 katyusza 的大作中提到: 】 : 我的猜测是如果子程序放在中间, : 那么执行到它的时候不管有没有call它它都会执行-_- : 但是如果放在末尾, : ................... 有call和没有call肯定是有区别的,不过都用了强制的call跳转的话,程序的流程就是程序1--call调用子程序--程序2,无论怎样都是一样的吧,难道是lcall和acall调用ROM地址的原因?不过那好像不能通过编译吧 子程序能放程序末尾,短跳指令总不能都放程序末吧,位置应该可以这样放 ☆─────────────────────────────────────☆ sealhuang (滚蛋前做个水男) 于 (Tue Sep 1 09:37:10 2009) 提到: 个人感觉,第一种写法先通过call调用了子程序,执行完毕后以ret又开始继续执行call的下一条指令,也就是说子程序会执行两次。第二种写法感觉稍好一点,但至于会不会在最后又执行一次子程序,要看LZ的想法了。 感觉汇编程序的顺序很看重编者的想法。 不知道对不对,大家轻拍。 ☆─────────────────────────────────────☆ cyenux (cyenux) 于 (Tue Sep 1 10:16:19 2009) 提到: 【 在 sealhuang 的大作中提到: 】 : 个人感觉,第一种写法先通过call调用了子程序,执行完毕后以ret又开始继续执行call的下一条指令,也就是说子程序会执行两次。第二种写法感觉稍好一点,但至于会不会在最后又执行一次子程序,要看LZ的想法了。 : 感觉汇编程序的顺序很看重编者的想法。 : 不知道对不对,大家轻拍。 额,记起来了,的确是这个问题,子程序在程序中间的时候好像要接一个条件跳~ ☆─────────────────────────────────────☆ katyusza (ka) 于 (Tue Sep 1 15:23:09 2009) 提到: 我的感觉是, 子程序在程序中间的话, 那么如果前面call子程序的话子程序会执行一遍, 然后程序“自然而然地”运行到了子程序的话子程序又会执行一遍-_- 所以要么子程序在中间、但是额外加个跳转让主程序跳过子程序, 要么子程序放在末尾,是这么回事儿吧? 【 在 cyenux (cyenux) 的大作中提到: 】 : 额,记起来了,的确是这个问题,子程序在程序中间的时候好像要接一个条件跳~ ☆─────────────────────────────────────☆ sealhuang (滚蛋前做个水男) 于 (Tue Sep 1 15:57:52 2009) 提到: 其实放在末尾的话如果不加处理也会再执行一遍,好像有点废话了... 看自己的想法了,比如加个判断以决定是否执行。 【 在 katyusza 的大作中提到: 】 : 我的感觉是, : 子程序在程序中间的话, : 那么如果前面call子程序的话子程序会执行一遍, : ................... ☆─────────────────────────────────────☆ afeionline (afeionline) 于 (Fri Sep 4 12:58:39 2009) 提到: 居然有人会用第一种格式?自找麻烦。 在没有控制语句的时候,程序是顺序执行的,把函数写到主函数体内,自然会自动执行到,不需要调用,但是当碰到ret时,就会出问题,因为没有调用的压栈,自然ret的出栈内容都是无效的,程序直接跑乱! 汇编程序一般用这个结构(个人意见): org 0000h ajmp main org 0003h .......... ;中断跳转代码 org 0100h main; 。。。。。。 sjmp $ ;主程序结束,死循环,相当于C里的while (1); sub1: ....... ret ISR1: ...... reti end ☆─────────────────────────────────────☆ yihang (Goodluckfly) 于 (Fri Sep 4 13:53:05 2009) 提到: 【 在 katyusza 的大作中提到: 】 : 初学8051单片机, : 调汇编程序的时候发现子程序的位置对运行结果有影响, : 如下(1)和(2)所示。 : ................... 代码是按顺序执行的 ☆─────────────────────────────────────☆ katyusza (ka) 于 (Mon Sep 7 10:56:59 2009) 提到: re,多谢多谢, 我也是这么想的~ 【 在 afeionline (afeionline) 的大作中提到: 】 : 居然有人会用第一种格式?自找麻烦。 : 在没有控制语句的时候,程序是顺序执行的,把函数写到主函数体内,自然会自动执行到,不需要调用,但是当碰到ret时,就会出问题,因为没有调用的压栈,自然ret的出栈内容都是无效的,程序直接跑乱! : 汇编程序一般用这个结构(个人意见): : ................... ☆─────────────────────────────────────☆ wuqiang0379 (小强) 于 (Sat Sep 19 22:11:23 2009) 提到: call指令在转入子程序的同时(程序PC指针指向子程序入口地址),会把当前PC值+1压入堆栈,为了以后返回,接着执行主程序中的下条程序。在子程序中遇到ret指令,会把堆栈中的地址弹出给PC,从而执行主程序中的下条程序。 你的写法,第一次可以从子程序返回,但会再次执行子程序,因为子程序是主程序的下条程序,在子程序中又会遇到ret指令,再次把堆栈中的地址弹给PC,堆栈中此时已为空,数据是0000H,这个0000H给PC后,程序会从开头执行,也就是从main开始,从而进入死循环。 ☆─────────────────────────────────────☆ katyusza (ka) 于 (Sun Sep 20 20:21:27 2009) 提到: zan! 讲的太好了,多谢多谢~ 【 在 wuqiang0379 (小强) 的大作中提到: 】 : call指令在转入子程序的同时(程序PC指针指向子程序入口地址),会把当前PC值+1压入堆栈,为了以后返回,接着执行主程序中的下条程序。在子程序中遇到ret指令,会把堆栈中的地址弹出给PC,从而执行主程序中的下条程序。 : 你的写法,第一次可以从子程序返回,但会再次执行子程序,因为子程序是主程序的下条程序,在子程序中又会遇到ret指令,再次把堆栈中的地址弹给PC,堆栈中此时已为空,数据是0000H,这个0000H给PC后,程序会从开头执行,也就是从main开始,从而进入死循环。
订阅后,新回复会通过你的通知中心匿名送达。
0 条回复
暂无回复 · 你可以订阅本帖等待新回复。