void delay1(unsigned char i)
{
    while(--i);
}
反汇编代码如下:

执行DJNZ指令需要2个机器周期,RET指令同样需要2个机器周期,根据输入t,在不计算调用delay()所需时间的情况下,具体时间延时如下:
t
Delay Time (us)
1
2×1+2 =4
2
2×2+2=6
N
2×N+2=2(N+1)


当在main函数中调用delay(1)时, 进行反汇编如下:

调用delay()时,多执行了两条指令,其中MOV R, #data需要1个机器周期,LJMP需要2个机器周期,即调用delay()需要3us.

Keil C仿真截图与计算过程:



加上调用时间,准确的计算时间延时与Keil C仿真对比如下:(可见,仿真结果和计算结果是很接近的)
t
Delay Time (us)
仿真11.0592Mhz时钟(us)
1
3+2×1+2 =7 | 7.7(实际)
7.60
2
3+2×2+2=9 | 9.9
9.76
N
3+2×N+2=2N+5 | (2N+5)*1.1
/
3
11 | 12.1
11.94
15
35 | 38.5 
37.98
100
205 | 225.5
222.44天涯 delay
255
515 | 566.5
558.81

也就是说,这个延时函数的精度为2us,最小的时间延时为7us,最大的时间延时为3+255×2+2=515us.   
实际中使用11.0592MHz的时钟,这个延时函数的精度将为2.2us,最小时间延时为7.7us, 最大时间延时为566.5us.