+ -
当前位置:首页 → 问答吧 → PHP源代码分析:OPCODE列表及功能简介[Draft, 2008.11.14更新]

PHP源代码分析:OPCODE列表及功能简介[Draft, 2008.11.14更新]

时间:2008-11-11

来源:互联网

最新的更新请参考:http://www.phpinternals.com/opcode.php

Opcode是operation code(操作码)的简称。是Zend Engine产生的中间代码,有点类似于汇编语言。opcode是一个四元组,(opcode, op1, op2, result),它们分别代表操作码,第一操作数,第二操作数,结果。在Zend Engine的实现中,opcode使用下面的结构来实现的。[code]
struct _zend_op {
opcode_handler_t handler;/ * OPCODE处理函数 */
znode result;   /* 本OPCODE操作结果,根据不同的opcode有不同的含义 */
znode op1; /* 第一操作数 */
znode op2;  /* 第二操作数 */
ulong extended_value; /* 与OPCODE有关的扩展值,例如: CAST中保存的就是目标类型 */
uint lineno;              /* OPCODE对应的代码的行号 */
zend_uchar opcode; /* OPCODE代码 */
};
[/code]在这个结构中, handler是一个函数指针,指向本opcode对应的虚拟机中的处理函数。result是一个znode类型的变量,用于保存操作结果。op1, op2分别是该opcode对应的两个操作数。op1, op2, result在不同的opcode中有不同的含义,不是每个opcode都有这三个变量。extended_value保存的是与opcode有关的扩展值。lineno是该opcode对应的源代码的行号,这个调试错误定位时非常有用;最后一个zend_uchar表示就是这个opcode的代码。因为同一个opcode,由于操作数的类型不同,可能会对应不同的处理函数,因此Zend Engine在实现时在每个_zend_op结构中都保留了handler指针,这样可以提高虚拟机的处理效率。

如果大家对什么是OPCODE不了解,请参考原创版块中laruence的更详细介绍文章。

下面以将PHP Zend Engine使用的每个OPCODE的功能简要说明如下:
(本表按PHP5.3alpha2列出,尚不完整,所有的opcode的功能都是根据本人的理解写出,有些opcode的功能可能有误,欢迎大家指正)





Opcode代码



ver


含义


ZEND_NOP

0



空操作
ZEND_ADD

1




ZEND_SUB

2




ZEND_MUL

3




ZEND_DIV

4




ZEND_MOD

5



求模
ZEND_SL

6



左移位 Shift Left
ZEND_SR

7



右移位 Shift Right
ZEND_CONCAT

8



字符串连接
ZEND_BW_OR

9



按位或
ZEND_BW_AND

10



按位与
ZEND_BW_XOR

11



按位异或
ZEND_BW_NOT

12



按位非
ZEND_BOOL_NOT

13



逻辑非!
ZEND_BOOL_XOR

14



逻辑异或 XOR
ZEND_IS_IDENTICAL

15



===
ZEND_IS_NOT_IDENTICAL

16



!==
ZEND_IS_EQUAL

17



==
ZEND_IS_NOT_EQUAL

18



<>,!=
ZEND_IS_SMALLER

19



<
ZEND_IS_SMALLER_OR_EQUAL

20



<=
ZEND_CAST

21



类型强制转换,目标类型extend_value
ZEND_QM_ASSIGN

22



?: 操作赋值
ZEND_ASSIGN_ADD

23



+=
ZEND_ASSIGN_SUB

24



-=
ZEND_ASSIGN_MUL

25



*=
ZEND_ASSIGN_DIV

26



/=
ZEND_ASSIGN_MOD

27



%=
ZEND_ASSIGN_SL

28



<<=
ZEND_ASSIGN_SR

29



>>=
ZEND_ASSIGN_CONCAT

30



.=
ZEND_ASSIGN_BW_OR

31



|=
ZEND_ASSIGN_BW_AND

32



&=
ZEND_ASSIGN_BW_XOR

33



^=
ZEND_PRE_INC

34



++前自增 ++$a
ZEND_PRE_DEC

35



--前自减 --$a
ZEND_POST_INC

36



后自增++ $a ++
ZEND_POST_DEC

37



后自减-- $a--
ZEND_ASSIGN

38



赋值=
ZEND_ASSIGN_REF

39



引用赋值 =&
ZEND_ECHO

40



ECHO
ZEND_PRINT

41



PRINT
ZEND_JMP

42



无条件跳转指令
ZEND_JMPZ

43



条件跳转
ZEND_JMPNZ

44



ZEND_JMPZNZ

45



ZEND_JMPZ_EX

46



ZEND_JMPNZ_EX

47



ZEND_CASE

48



CASE操作符
ZEND_SWITCH_FREE

49



SWITCH
ZEND_BRK

50



BREAK
ZEND_CONT

51



CONTINUE
ZEND_BOOL

52



BOOL转换
ZEND_INIT_STRING

53



初始化字符串
ZEND_ADD_CHAR

54



将字符加到字符串
ZEND_ADD_STRING

55



将字符串加到字符串
ZEND_ADD_VAR

56



将变量加到字符串
ZEND_BEGIN_SILENCE

57



错误屏蔽开始
ZEND_END_SILENCE

58



错误屏蔽结束
ZEND_INIT_FCALL_BY_NAME

59



初始化通过名称调用函数
ZEND_DO_FCALL

60



函数调用
ZEND_DO_FCALL_BY_NAME

61



通过名称调用函数
ZEND_RETURN

62



函数返回
ZEND_RECV

63



函数声明时传递参数
ZEND_RECV_INIT

64



函数声明时传递参数,用默认值初始化
ZEND_SEND_VAL

65



函数调用时传递值作为参数
ZEND_SEND_VAR

66



函数调用时传递变量作为参数
ZEND_SEND_REF

67



函数调用时传递引用作为参数
ZEND_NEW

68



new 操作
ZEND_INIT_NS_FCALL_BY_NAME

69


5.3


命名空间函数调用
ZEND_FREE

70



free操作
ZEND_INIT_ARRAY

71



数组初始化
ZEND_ADD_ARRAY_ELEMENT

72



添加数组元素
ZEND_INCLUDE_OR_EVAL

73



include/require/eval操作
ZEND_UNSET_VAR

74


5.1


UNSET操作
ZEND_UNSET_DIM

75


5.1


ZEND_UNSET_OBJ

76


5.1


ZEND_FE_RESET

77


5.1


FOREACH操作
ZEND_FE_FETCH

78



FOREACH操作
ZEND_EXIT

79



EXIT
ZEND_FETCH_R

80



这一系列OPCODE用于获取各种类型的变量地址,分别用于不同的操作。R:只读,W:只写,RW:读写。
DIM – 数组
OBJ – 对象
ZEND_FETCH_DIM_R

81



ZEND_FETCH_OBJ_R

82



ZEND_FETCH_W

83



ZEND_FETCH_DIM_W

84



ZEND_FETCH_OBJ_W

85



ZEND_FETCH_RW

86



ZEND_FETCH_DIM_RW

87



ZEND_FETCH_OBJ_RW

88



ZEND_FETCH_IS

89



取出变量地址,用于IS*测试。IS*测试指的是对变量进行ISSET 或ISEMPTY测试。


ZEND_FETCH_DIM_IS

90



ZEND_FETCH_OBJ_IS

91



ZEND_FETCH_FUNC_ARG

92



获取函数参数地址
ZEND_FETCH_DIM_FUNC_ARG

93



ZEND_FETCH_OBJ_FUNC_ARG

94



ZEND_FETCH_UNSET

95



获取变量地址,用于UNSET
ZEND_FETCH_DIM_UNSET

96



ZEND_FETCH_OBJ_UNSET

97



ZEND_FETCH_DIM_TMP_VAR

98




ZEND_FETCH_CONSTANT

99


5.0


取得常量地址
ZEND_GOTO

100


5.3


GOTO 操作
ZEND_EXT_STMT

101



extension statement
ZEND_EXT_FCALL_BEGIN

102



extension function call begin
ZEND_EXT_FCALL_END

103



extension function call end
ZEND_EXT_NOP

104



extension noop
ZEND_TICKS

105



TICKS函数,5.3中过时,6.0取消
ZEND_SEND_VAR_NO_REF

106




参数传递
ZEND_CATCH

107


5.0


异常处理捕获异常
ZEND_THROW

108



异常处理抛出异常
ZEND_FETCH_CLASS

109



使用对象名称获取对象指针
ZEND_CLONE

110



对象克隆
ZEND_INIT_METHOD_CALL

112



对象方法调用初始化
ZEND_INIT_STATIC_METHOD_CALL

113



对象静态方法调用初始化
ZEND_ISSET_ISEMPTY_VAR

114



标量类型变量IS*测试
ZEND_ISSET_ISEMPTY_DIM_OBJ

115



数组或对象类型变量IS*测试
ZEND_PRE_INC_OBJ

132



对象属性前自增 ++$obj->prop
ZEND_PRE_DEC_OBJ

133



对象属性前自减 --$obj->prop
ZEND_POST_INC_OBJ

134



对象属性后自增 $obj->prop++
ZEND_POST_DEC_OBJ

135



对象属性后自减 $obj->prop--
ZEND_ASSIGN_OBJ

136



对象赋值
ZEND_INSTANCEOF

138



instanceof操作符
ZEND_DECLARE_CLASS

139



类声明
ZEND_DECLARE_INHERITED_CLASS

140



继承类声明
ZEND_DECLARE_FUNCTION

141



函数声明
ZEND_RAISE_ABSTRACT_ERROR

142



实例化抽象类错误
ZEND_DECLARE_CONST

143


5.3


常数声明
ZEND_ADD_INTERFACE

144



类声明时添加接口
ZEND_DECLARE_INHERITED_CLASS_DELAYED

145



声明继承类,使用delayed early binding
ZEND_VERIFY_ABSTRACT_CLASS

146



抽象类验证
ZEND_ASSIGN_DIM

147



数组元素赋值
ZEND_ISSET_ISEMPTY_PROP_OBJ

148



对象属性IS*测试
ZEND_HANDLE_EXCEPTION

149



异常处理
ZEND_USER_OPCODE

150


5.1


用户自定义OPCODE处理器
ZEND_U_NORMALIZE

151


6.0



规范化标识符名
ZEND_JMP_SET

152


5.3


无条件跳转,并设置RESULT
ZEND_DECLARE_LAMBDA_FUNCTION

153


5.3


声明LAMBDA函数




作者: Altair   发布时间: 2008-11-11

发表于 2008-11-11 11:11

这个时间可真好,必是大作

作者: 甲骨文   发布时间: 2008-11-11

分享一个可以查看opcodes的软件.在dos目录下直接运行"opdump 1.php"即可.

opdumper.rar (1.67 MB)

下载次数:25

2008-11-13 22:05

作者: 0hudu   发布时间: 2008-11-11

原帖由 xiaojie515 于 2008-11-13 22:05 发表
分享一个可以查看opcodes的软件.在dos目录下直接运行"opdump 1.php"即可.
这个小程序是我写的,还很不完善。现在已经有新版本发布出来啦。

作者: xiaojie515   发布时间: 2008-11-13

好文, 总结的很详细, mark

作者: Altair   发布时间: 2008-11-14

原帖由 laruence 于 2008-11-14 12:29 发表
好文, 总结的很详细, mark
每个OPCODE的功能还没有仔细推敲,欢迎指正。

作者: laruence   发布时间: 2008-11-14

这个时间实在是太强了!

作者: Altair   发布时间: 2008-11-14