2012-07-23 20 views
8

Próbuję zrozumieć kod operacyjny dla prostego kodu.Zrozumienie kodu operacji PHP w instrukcji if

Kod jest:

<?php 

$a = TRUE; 

$b = FALSE; 

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

Kod op dla powyższego kodu jest:

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, 

Próbuję zrozumieć, co dzieje się na linii 7, jak jest ocena zrobić? Ile wartości zawiera wyrażenie "do oceny"? Wprowadza 3 wartości lub wprowadza 2 wartości o wartości $ a i wartości $ b, a wyrażenie z nawiasów if jest następnie oceniane?

Przeczytałem instrukcję dla JMPZ_EX, Rozumiem, co dzieje się w kodzie operacyjnym do kroku 2 po tym, jak jest trochę pomieszany i bardzo trudno mi zrozumieć, jakie są dokładne kroki, które php jest robić.

Kolejną rzeczą, którą muszę zrozumieć, jest to, jakie są wszystkie gałęzie w kodzie operacji, z której z tych gałęzi będą używane na końcu?

+0

'&&' jest operatorem zwarcia. –

+0

@KarolyHorvath że wiem, muszę zrozumieć kroki, które php robi z powyższego kodu operacji. – Starlays

+0

Po prostu mówię, że już wiesz, jak powinno się to zachowywać, więc ... –

Odpowiedz

2

Jeśli nie jesteś biegły w ASM, myślę, że najprostszym sposobem, aby zrozumieć, co dzieje się patrzy na ten sam kod, czytając jego (prawie) 1: 1 reprezentację w PHP:

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

reprezentacja pośredni jest oparty na negacjach twoich rzeczywistych klauzul, aby przeskoczyć kod znajdujący się w bloku if.

Jeśli naprawdę chcesz zrozumieć, w jaki sposób PHP przekształca dane wejściowe w tę tablicę kodów, musisz zapoznać się z wewnętrznymi kodami PHP, ale nie przed badaniem the dragon book, szczególnie części o pośredniej reprezentacji, która jest częścią procesu kompilacji .

Pozostałe kody opcyjne to "szum tła", wartości pośrednie, a nawet jedna instrukcja, która nie ma żadnego sensu: 9 6 > JMP ->7, która po prostu istnieje prawdopodobnie dlatego, że nie ma sensu wkładać wysiłku w sprawienie, aby parser PHP wypluwał najbardziej optymalna tablica kodów dla ZendVM, która będzie działać.

2
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 

Idąc przez numery linii #

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

JMPZ oznacza skok do kodu, jeśli wartość wynosi 0. Nie jestem pewna specyficzna różnica JMPZ_EX wygląda na to pozwala powrót wyniku boolowskiego.

Więc:

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 

Kilka uwag:

  • Wydaje się, że JMPZ_EX jest konieczne w tym przypadku, ale byłoby przydatne w bardziej złożony if gdzie trzeba użyć wartości w obliczanie dalszych wartości.
  • 6 JMP -7 jest prawdopodobnie tam, aby pozwolić na blok else. Jeśli była to główna część bloku if, to można było przeskoczyć fragment kodu, który był blokiem else.