独闷闷网
标题:
51单片机main函数如果没有while(1),执行到main最后一行时程序会重新运行吗?已解答。
[打印本页]
作者:
jianhong_wu
时间:
2015-3-2 08:15
标题:
51单片机main函数如果没有while(1),执行到main最后一行时程序会重新运行吗?已解答。
王华—四川:
#include <reg52.h>
void Delay10ms(unsigned int);
void main()
{
/* while(1) */
// {
P2 = 0x00; //置P0口为低电平
Delay10ms(50); //调用延时程序
P2 = 0xff; //置P0口为高电平
Delay10ms(50); // 调用延时程序
// }
}
void Delay10ms(unsigned int c)
{
unsigned char a,b;
for(;c>0;c--)
for(b=38;b>0;b--)
for(a=130;a>0;a--);
}
复制代码
为啥子while的作用去不掉呢?灯还在闪烁呀?
斌+汕头:
问你,main函数中最后一条指令执行完后,应该跳转到哪里?
王华—四川:
呃,不晓得,求指点。
斌+汕头:
因为51单片机我们开发,main函数并没有使用标准的C语言。
main
{
***********
***********
}
最后是跳转到mian;
详细分析如下:
一、没有while(1)示例代码(示例一):
#include <reg52.h>
void delay(int x);
void main()
{
P2 = ~P2;
delay(2);
P1=0;
}
void delay(int x)
{
for(;x>0;x--);
}
复制代码
二、反汇编
C:0x0000 020024 LJMP C:0024
10: void delay(int x)
11: {
12: for(;x>0;x--);
C:0x0003 D3 SETB C
C:0x0004 EF MOV A,R7
C:0x0005 9400 SUBB A,#0x00
C:0x0007 EE MOV A,R6
C:0x0008 6480 XRL A,#P0(0x80)
C:0x000A 9480 SUBB A,#P0(0x80)
C:0x000C 4007 JC C:0015
C:0x000E EF MOV A,R7
C:0x000F 1F DEC R7
C:0x0010 70F1 JNZ delay(C:0003)
C:0x0012 1E DEC R6
C:0x0013 80EE SJMP delay(C:0003)
13: }
C:0x0015 22 RET
3: void main()
4: {
5: P2 = ~P2;
C:0x0016 63A0FF XRL P2(0xA0),#0xFF
6: delay(2);
C:0x0019 7F02 MOV R7,#0x02
C:0x001B 7E00 MOV R6,#0x00
C:0x001D 120003 LCALL delay(C:0003)
7: P1=0;
C:0x0020 E4 CLR A
C:0x0021 F590 MOV P1(0x90),A
8: }
C:0x0023 22 RET
C:0x0024 787F MOV R0,#0x7F
C:0x0026 E4 CLR A
C:0x0027 F6 MOV @R0,A
C:0x0028 D8FD DJNZ R0,C:0027
C:0x002A 758107 MOV SP(0x81),#0x07
C:0x002D 020016 LJMP main(C:0016)
复制代码
三、解释说明(示例一):
1、汇编都是从0x0000处开始运行程序,反汇编中,0x0000处直接跳转至0x0024;
2、0x24 ~ 0x002D为启动代码,该段代码的主要功能是,清内存、置堆栈、跳转至main。
3、 RET :子程序返回指令, LCALL:子程序调用指令。
4、若main函数中没有while(1)循环,则main函数最后一条指令是ret,也就是说main函数被当作子函
数一样调用了,有ret返回。那么问题来了,如下:
主函数不能被调用,只能被执行,也就是说只有ret,没有call。
主函数只能存在一个,在启动代码中main是使用跳转指令进入的,并不是使用LCALL,如若使用ret进行
返回,必然导致程序复位,跳转至0x0000处,程序将重新运行。
欢迎光临 独闷闷网 (http://dumenmen.com/)
Powered by Discuz! X3.2