opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定。 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数。 这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等。
通常opcode还有另一种称谓:字节码(byte codes)。 例如Java虚拟机(JVM),.NET的通用中间语言(CIL: Common Intermeditate Language)等等。
1. Opcode简介
opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定。 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数。 这些操作数可能是寄存器中的值,堆栈中的值,某块内存的值或者IO端口中的值等等
通常opcode还有另一种称谓: 字节码(byte codes)。 例如Java虚拟机(JVM),.NET的通用中间语言(CIL: Common Intermeditate Language)等等
PHP中的opcode则属于前面介绍中的后着,PHP是构建在Zend虚拟机(Zend VM)之上的。PHP的opcode就是Zend虚拟机中的指令(基于Zend的中间代码)
Relevant Link:
http://www.luocong.com/learningopcode/doc/1._%E4%BB%80%E4%B9%88%E6%98%AFOpCode%EF%BC%9F.htm
2. PHP中的Opcode
0x1: 数据结构
在PHP实现内部,opcode由如下的结构体表示
/php-5.6.17/Zend/zend_compile.h
struct _zend_op {opcode_handler_t handler; // 执行该opcode时调用的处理函数znode_op op1; // opcode所操作的操作数znode_op op2; // opcode所操作的操作数znode_op result;ulong extended_value;uint lineno;zend_uchar opcode; // opcode代码zend_uchar op1_type;zend_uchar op2_type;zend_uchar result_type;};
和CPU的指令类似,有一个标示指令的opcode字段,以及这个opcode所操作的操作数,PHP不像汇编那么底层, 在脚本实际执行的时候可能还需要其他更多的信息,extended_value字段就保存了这类信息, 其中的result域则是保存该指令执行完成后的结果
例如如下代码是在编译器遇到print语句的时候进行编译的函数
/php-5.6.17/Zend/zend_compile.c
void zend_do_print(znode *result, const znode *arg TSRMLS_DC) /* {{{ */{ //新创建一条zend_op zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC);//将新建的zend_op的返回值类型设置为临时变量(IS_TMP_VAR),因为print中的内存仅仅为了临时输出,并不需要保存opline->result_type = IS_TMP_VAR;//为临时变量申请空间opline->result.var = get_temporary_variable(CG(active_op_array));//指定opcode为ZEND_PRINTopline->opcode = ZEND_PRINT;//将传递进来的参数赋值给这条opcode的第一个操作数SET_NODE(opline->op1, arg);SET_UNUSED(opline->op2);GET_NODE(result, opline->result);}
新闻热点
疑难解答