51用中断完成单个按键控制多个LED状态变换

以下是题的描述:
要求单片机上电复位后,8 位 LED 灯隔一个亮一个,当按下接在外部中断 1 管脚上的按键时,8 位 LED 从左向右做单灯亮的流水效果;再次按下该按键时,LED 做从右向左单灯亮流水效果;第三次按下该按键时,8 位 LED 灯间隔闪烁;第四次按下该按键时,8 位 LED 灯回到单片机复位时的状态。
我的代码,第一次将LED变换的LED_blink01234()几个函数放在了中断函数里执行,仿真发现虽然立马就变化了状态,但一次亮灯结束后状态又回到了前一次没有执行完的函数,将前一次剩余状态执行完后才继续该次状态;
然后改为这个代码,但只有把第一次状态亮完后才会改变为第二次状态。

有什么办法可以外部中断函数结束后立马从头开始执行而不是从中断点开始继续执行?或是只要启动了中断,就立马结束当前语句转到后面的语句?

//现在遇到两个问题,若在
#include<REG52.H>
sbit K=P3^3;
unsigned char cnt=0;
unsigned char flag=0;
void Delay(unsigned char t){
    unsigned char i,j;
    for(i=0;i<t;i++)
        for(j=0;j<200;j++);
}
void LED_blink0(){

    unsigned char discom=0x01;
    do{
        P2=~discom;
        Delay(200);
        discom<<=2;
    }while(discom!=0x00);

}
void Init(){
    EX0=EX1=1;//允许外部中断
    IT0=IT1=1;//==1为下降沿触发
    EA=1;
}
void LED_blink1(){//LED_blink1234分别为四个不同流水的状态
        unsigned char discom=0x01;
        do{
            P2=~discom;
            Delay(200);
            discom<<=1;
        }while(discom!=0x00);
}
void LED_blink2(){
        unsigned char discom=0x80;
        do{
            P2=~discom;
            Delay(200);
            discom>>=1;
        }while(discom!=0x00);
}
void LED_blink3(){
    P2=0x55;
    Delay(200);
    P2=~0x55;
    Delay(200);
}
void sr_int1() interrupt 2{
    cnt++;
    flag=1;
    if(cnt==4) cnt=0,flag=0;
}
void main(){
    Init();
    while(1){
        if(flag==1){
            switch(cnt){
                case 1:
                    LED_blink1();
                    break;
                case 2:
                    LED_blink2();
                    break;
                default:
                    LED_blink3();
            }
        }
        if(flag==0){
            LED_blink0();
        }
    }
}

在第四次按键按下后的中断里面跳转到地址0,((void(code *)(void))0x0000)(); 不行就查一下软件复位