PHP源代码分析:OPCODE列表及功能简介[Draft, 2008.11.14更新]
时间:2008-11-11
来源:互联网
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

opdumper.rar (1.67 MB)
作者: 0hudu 发布时间: 2008-11-11
分享一个可以查看opcodes的软件.在dos目录下直接运行"opdump 1.php"即可.
作者: xiaojie515 发布时间: 2008-11-13
作者: Altair 发布时间: 2008-11-14
好文, 总结的很详细, mark
作者: laruence 发布时间: 2008-11-14
作者: Altair 发布时间: 2008-11-14
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28