Question

I'm trying to understand the op code for an simple code.

The code is:

<?php

$a = TRUE;

$b = FALSE;

if($a && $b) {
    echo 'done';
}

The op code for the above code is:

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, 

I'm trying to understand what is happening on line 7, how is the evaluation done? How many values does it enter in the expression of if for evaluation? It enters 3 values, or it enters the 2 values the value of $a and value of $b and the expression from the parentheses of if is evaluated afterwards?

I have read the manual for JMPZ_EX, I've understand what is happening in the op code until step 2 after that is a little bit mixed up and it is very hard to me to understand what are exact steps that php is doing.

Another thing that I need to understand is what are all the branches in the op code, which of all that branches will be used at the end?

Was it helpful?

Solution

Unless you are proficient at ASM, I think the easiest way to understand what is happening is looking at the same code by reading its (almost) 1:1 representation in PHP:

if(!$a) goto end;
if(!$b) goto end;
echo 'done';
end: return 0;

The intermediate representation is based on the negations of your actual clauses to make a jump over the code contained in the if block.

If you want to really understand how PHP transforms its input to this opcode array, you'll have to learn about PHP internals, but not before studying the dragon book, particularily the parts about intermediate representation, which is part of the compilation pipeline.

The rest of the opcodes are "background noise", intermediate values, or even one instruction which makes no sense 9 6 > JMP ->7 which simply exists probably because it didn't make sense to put the effort into making the PHP parser spit out the most optimal opcode array for the ZendVM to be run by.

OTHER TIPS

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

Going by the line numbers #

0 assigns true to !0, !0 is just the internal representation of $A
1 assigns true to !1, !1 is $B

JMPZ means to jump to code if the value is 0. I'm not sure the specific difference of JMPZ_EX it looks like it allows the return of a boolean result.

So:

2 JMPZ_EX, Jump to #4 (->4) if !0 ($A) is 0 (FALSE) and assign the result to ~2

3 BOOL !1 return ~2. ~2 is now equal to the BOOLean value of !1 ($B)
4 JMPZ ~2, Jump to #7 if ~2 is zero

5 ECHO, our echo statement. If any of the JMPZ had jumped, this part would be skipped.
6 JMP -7, jumps to #7
7 RETURN, ends the function call

Some notes:

  • It seems like the JMPZ_EX is unnecessary in this case, but would be useful in more complex if statements where you need to use the value in calculating further values.
  • 6 JMP -7 is probably in there to allow for an else block. If this was the main part of the if block, finishing it could then jump over the portion of code that was the else block.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top