楼主的图画的很晕啊,不过我还是细细的看了一遍。提出几个疑问:
<1>call空标号的说法有何依据?空标号原理是什么?
<2>上面提到的堆栈是用来存放什么数据的?for堆栈又指什么?
<3>"延迟环境变量,就是启用堆栈"又有什么根据?
我的看法:
<1>对于上述例子中的call , 可以运行的情况。楼主认为是空标号。既然是空标号,楼主又加个逗号是何意?加了逗号还是空标号吗?我测试过call后加空格,逗号,分号都可以正确运行。并且空格,逗号,分号都是批处理的分隔符。for对文本或文件解析时delims默认为空格和逗号,eol默认为分号。并且使用call做调用子程序用时都需要加冒号的。
<2>楼主说call,echo %%x%% 时,首先把0入栈,然后发觉是空标号,所以就又出栈。这样做有何意义?换个角度,从底层来看,每次调用子程序过程中,call包含两层意思:首先把当前指令的段地址与偏移地址入栈,其次执行跳转指令,也就是跳转到标签所在的地址。并且子程序结束后会有一个 goto :eof,表示子程序结束。这个goto :eof也就是之前入栈的地址出栈,程序接着上面调用子程序的下一条执行。由此看来,入栈的原因是保护现场,需要入栈的是指令的地址,而不是程序需要处理的数据。
<3>"延迟环境变量,就是启用堆栈",这样的说法我头一次听说。对于for中遇到开启变量延迟的变量就入栈的说法,不知具体有什么思考、根据。
<4>我想这又涉及到一个call与变量延迟机制的问题,想要完全弄明白还需要从机制入手。对于楼主的行为我表示肯定,我想这也会吸引更多的人来参与讨论的。一个新理论的提出确实需要来自多方面的检验。
附:一个简单的例子,就是查看开启变量延迟和使用call后的执行时间对比。
- @echo off&setlocal enabledelayedexpansion
- set str=123
- echo %time%
- for /l %%i in (1,1,10000) do echo %str%>nul
- echo %time%
- for /l %%i in (1,1,10000) do echo !str!>nul
- echo %time%
- for /l %%i in (1,1,10000) do call echo %%str%%>nul
- echo %time%
- pause
复制代码
|