我正在尝试理解一个简单代码的操作码.
代码是:
<?php
$a = TRUE;
$b = FALSE;
if($a && $b) {
echo 'done';
}
Run Code Online (Sandbox Code Playgroud)
上述代码的操作码是:
php -dvld.active=1 test.php
Finding entry points
Branch analysis from position: 0
Jump found. Position 1 = 3, Position 2 = 4
Branch analysis from position: 3
Jump found. Position 1 = 5, Position 2 = 7
Branch analysis from position: 5
Jump found. Position 1 = 7
Branch analysis from position: 7
Return found
Branch analysis from position: 7
Branch analysis from position: 4
filename: /home/starlays/learning/test.php
function name: (null)
number of ops: 8
compiled vars: !0 = $a, !1 = $b
line # * op fetch ext return operands
---------------------------------------------------------------------------------
3 0 > ASSIGN !0, true
5 1 ASSIGN !1, false
7 2 > JMPZ_EX ~2 !0, ->4
3 > BOOL ~2 !1
4 > > JMPZ ~2, ->7
8 5 > ECHO 'done'
9 6 > JMP ->7
10 7 > > RETURN 1
branch: # 0; line: 3- 7; sop: 0; eop: 2; out1: 3; out2: 4
branch: # 3; line: 7- 7; sop: 3; eop: 3; out1: 4
branch: # 4; line: 7- 7; sop: 4; eop: 4; out1: 5; out2: 7
branch: # 5; line: 8- 9; sop: 5; eop: 6; out1: 7
branch: # 7; line: 10- 10; sop: 7; eop: 7
path #1: 0, 3, 4, 5, 7,
path #2: 0, 3, 4, 7,
path #3: 0, 4, 5, 7,
path #4: 0, 4, 7,
Run Code Online (Sandbox Code Playgroud)
我试图了解第7行发生了什么,评估是如何完成的?在评估的if表达式中输入了多少个值?它输入3个值,或者输入值为$ a的值和$ b的值,并且之后评估if的括号中的表达式?
我已经阅读了JMPZ_EX的手册 ,我已经理解了操作代码中发生了什么,直到第2步之后有点混乱,我很难理解php正在做什么的确切步骤.
我需要理解的另一件事是操作码中的所有分支是什么,最后将使用哪些分支?
除非您精通ASM,否则我认为了解正在发生的情况的最简单方法是通过阅读 PHP 中的(几乎)1:1 表示来查看相同的代码:
if(!$a) goto end;
if(!$b) goto end;
echo 'done';
end: return 0;
Run Code Online (Sandbox Code Playgroud)
中间表示基于实际子句的否定,以跳过块中包含的代码if。
如果你想真正理解 PHP 如何将其输入转换为这个操作码数组,你必须了解 PHP 内部原理,但在学习龙书之前,特别是关于中间表示的部分,它是编译管道的一部分。
其余的操作码是“背景噪声”、中间值,甚至是一条毫无意义的指令,它的9 6 > JMP ->7存在可能只是因为付出努力让 PHP 解析器吐出最佳的操作码数组没有意义。要运行的 ZendVM。