2012-07-23 44 views
8

Tôi đang cố gắng hiểu mã op cho một mã đơn giản.Hiểu mã op của PHP trong câu lệnh if

Mã này là:

<?php 

$a = TRUE; 

$b = FALSE; 

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

Mã op cho mã trên là:

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, 

Tôi đang cố gắng để hiểu những gì đang xảy ra trên dòng 7, làm thế nào là đánh giá thực hiện? Bao nhiêu giá trị nó nhập vào trong biểu thức của nếu để đánh giá? Nó nhập vào 3 giá trị, hoặc nó nhập vào 2 giá trị giá trị của $ a và giá trị của $ b và biểu thức từ dấu ngoặc đơn nếu được đánh giá sau đó?

Tôi đã đọc hướng dẫn cho JMPZ_EX, tôi đã hiểu những gì đang xảy ra trong mã op cho đến bước 2 sau đó là một chút hỗn hợp và rất khó để tôi hiểu các bước chính xác mà php là gì đang làm.

Một điều khác mà tôi cần phải hiểu là tất cả các nhánh trong mã op là gì, tất cả các nhánh nào sẽ được sử dụng ở cuối?

+0

'&&' là toán tử mạch ngắn. –

+0

@KarolyHorvath mà tôi biết, tôi cần phải hiểu các bước mà php đang làm từ mã op ở trên. – Starlays

+0

Tôi chỉ đang nói bạn đã biết cách xử lý, vì vậy ... –

Trả lời

2

Trừ khi bạn là thành thạo tại ASM, tôi nghĩ rằng cách dễ nhất để hiểu những gì đang xảy ra là nhìn vào mã tương tự bằng cách đọc (gần như) 1 của nó: 1 đại diện trong PHP:

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

Các đại diện trung gian dựa trên sự phủ định của các mệnh đề thực tế của bạn để nhảy qua mã có trong khối if.

Nếu bạn thực sự hiểu cách PHP chuyển đổi đầu vào của nó thành mảng opcode này, bạn sẽ phải tìm hiểu về nội bộ PHP, nhưng không phải trước khi nghiên cứu the dragon book, đặc biệt là các bộ phận về biểu diễn trung gian. .

Phần còn lại của opcodes là "tiếng ồn nền", giá trị trung gian hoặc thậm chí là một lệnh không có ý nghĩa 9 6 > JMP ->7 đơn giản tồn tại có thể vì không có ý nghĩa gì khi đưa trình phân tích cú pháp PHP nhổ ra mảng opcode tối ưu nhất cho ZendVM được điều hành bởi.

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 

Going by the số dòng #

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

JMPZ nghĩa để nhảy đến mã nếu giá trị là 0. Tôi không chắc chắn sự khác biệt cụ thể của JMPZ_EX có vẻ như nó cho phép trả về kết quả boolean.

Vì vậy:

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 

Một số lưu ý:

  • Nó có vẻ như các JMPZ_EX là không cần thiết trong trường hợp này, nhưng sẽ là hữu ích trong việc phức tạp hơn nếu báo cáo, nơi bạn cần phải sử dụng các giá trị trong tính toán các giá trị khác.
  • 6 JMP -7 có thể ở trong đó để cho phép chặn khác. Nếu đây là phần chính của khối nếu kết thúc, nó có thể nhảy qua phần mã là khối khác.
Các vấn đề liên quan