原创 由LJMP指令引出的思考

2007-10-24 20:04 6044 8 8 分类: MCU/ 嵌入式

很久没有使用汇编语言来写单片机了,今天想着写一段程序玩玩。在调试中出现了未能达到的效果,后来用单步执行方式发现在程序跳入子程序后,返回竟然回到了程序最开始的地方:0000H。仔细看程序发现在调用子程序的时候,居然使用了LJMP指令而不是LCALL/ACALL,所以才未达到预期的效果。


后来再改写程序,使用LCALL调用子程序,发现结果就正常了,可见是调用的时候使用了LJMP的缘故。但是转念一想,既然使用了这种非对称式的“调用返回”模式可以使得程序转向出现错误,那也可以反过来利用这种“错误”来到达某些目的,比如可以在程序的最后全部用RET指令来填充,这样如果程序出现“跑飞”的情况,而且跑飞到了这些区域,那就可以使得程序返回到0000H,而不致于出现死机等情况。也可以在烧写程序的时候填充RET的机器代码22在空白区域,也会有同样的效果。


上述讨论以Keil  uVision2为编译环境。以下附程序:


 
LED0 EQU P0.0
LED1 EQU P0.1
LED2 EQU P0.2
LED3 EQU P0.3



 ORG 0000H
 LJMP INITIAL
 ORG 0030H
INITIAL:
 CLR LED0
 SETB LED1
 SETB LED2
 CLR LED0


START: CPL LED0
 CPL LED1
 CPL LED2
 CPL LED3
 ;RET ;如果在这里加入RET指令,调试观察程序的跳转也会跳到0000H。
 LJMP SB_DELAY;这里没有使用LCALL指令,但后面的SB_DELAY却用了RET指令,
   ;会使程序跳到0000H处,可以通过单步调试看出
 LJMP START
 


DL_CNT0 EQU 0AH;外层循环的次数
DL_CNT1 EQU 7DH;内层循环的次数
SB_DELAY:
 MOV R0,#DL_CNT0
LP1_DELAY:
 MOV R1,#DL_CNT1
LP2_DELAY:
 NOP
 NOP
 DJNZ    R1,LP2_DELAY
      DJNZ R0,LP1_DELAY
 RET
        END


                                       writed by eleclike  2007-10-24

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
8
关闭 站长推荐上一条 /3 下一条