精华内容
下载资源
问答
  • Opcode
    2021-04-23 13:38:16

    什么是opcode缓存?

    当解释器完成对脚本代码的分析后,便将它们生成可以直接运行的中间代码,也称为操作码(Operate Code,opcode)。Opcode cache的目地是避免重复编译,减少CPU和内存开销。如果动态内容的性能瓶颈不在于CPU和内存,而在于I/O操作,比如数据库查询带来的磁盘I/O开销,那么opcode cache的性能提升是非常有限的。但是既然opcode cache能带来CPU和内存开销的降低,这总归是好事。

    现代操作码缓存器(Optimizer+,APC2.0+,其他)使用共享内存进行存储,并且可以直接从中执行文件,而不用在执行前“反序列化”代码。这将带来显着的性能加速,通常降低了整体服务器的内存消耗,而且很少有缺点。

    为什么要使用Opcode缓存?

    这得从PHP代码的生命周期说起,请求PHP脚本时,会经过五个步骤,如下图所示:

    Zend引擎必须从文件系统读取文件、扫描其词典和表达式、解析文件、创建要执行的计算机代码(称为Opcode),最后执行Opcode。每一次请求PHP脚本都会执行一遍以上步骤,如果PHP源代码没有变化,那么Opcode也不会变化,显然没有必要每次都重行生成Opcode,结合在Web中无所不在的缓存机制,我们可以把Opcode缓存下来,以后直接访问缓存的Opcode岂不是更快,启用Opcode缓存之后的流程图如下所示:

    有那些PHP opcode缓存插件?

    Optimizer+(Optimizer+于2013年3月中旬改名为Opcache,PHP 5.5集成Opcache,其他的会不会消失?)、eAccelerator、xcache、APC ...

    PHP opcode原理

    Opcode是一种PHP脚本编译后的中间语言,就像Java的ByteCode,或者.NET的MSL,举个例子,比如你写下了如下的PHP代码:

    echo "Hello World";

    $a = 1 + 1;

    echo $a;

    ?>

    PHP执行这段代码会经过如下4个步骤(确切的来说,应该是PHP的语言引擎Zend)

    Scanning(Lexing) ,将PHP代码转换为语言片段(Tokens)

    Parsing, 将Tokens转换成简单而有意义的表达式

    Compilation, 将表达式编译成Opocdes

    Execution, 顺次执行Opcodes,每次一条,从而实现PHP脚本的功能

    题外话:现在有的Cache比如APC,可以使得PHP缓存住Opcodes,这样,每次有请求来临的时候,就不需要重复执行前面3步,从而能大幅的提高PHP的执行速度。

    那什么是Lexing? 学过编译原理的同学都应该对编译原理中的词法分析步骤有所了解,Lex就是一个词法分析的依据表。 Zend/zend_language_scanner.c会根据Zend/zend_language_scanner.l(Lex文件),来输入的 PHP代码进行词法分析,从而得到一个一个的“词”,PHP4.2开始提供了一个函数叫token_get_all,这个函数就可以讲一段PHP代码 Scanning成Tokens;

    如果用这个函数处理我们开头提到的PHP代码,将会得到如下结果:

    Array

    (

    [0] => Array

    (

    [0] => 367

    [1] => Array

    (

    [0] => 316

    [1] => echo

    )

    [2] => Array

    (

    [0] => 370

    [1] =>

    )

    [3] => Array

    (

    [0] => 315

    [1] => "Hello World"

    )

    [4] => ;

    [5] => Array

    (

    [0] => 370

    [1] =>

    )

    [6] => =

    [7] => Array

    (

    [0] => 370

    [1] =>

    )

    [8] => Array

    (

    [0] => 305

    [1] => 1

    )

    [9] => Array

    (

    [0] => 370

    [1] =>

    )

    [10] => +

    [11] => Array

    (

    [0] => 370

    [1] =>

    )

    [12] => Array

    (

    [0] => 305

    [1] => 1

    )

    [13] => ;

    [14] => Array

    (

    [0] => 370

    [1] =>

    )

    [15] => Array

    (

    [0] => 316

    [1] => echo

    )

    [16] => Array

    (

    [0] => 370

    [1] =>

    )

    [17] => ;

    )

    分析这个返回结果我们可以发现,源码中的字符串,字符,空格,都会原样返回。每个源代码中的字符,都会出现在相应的顺序处。而,其他的比如标签,操作符,语句,都会被转换成一个包含俩部分的Array: Token ID (也就是在Zend内部的改Token的对应码,比如,T_ECHO,T_STRING),和源码中的原来的内容。

    接下来,就是Parsing阶段了,Parsing首先会丢弃Tokens Array中的多于的空格,然后将剩余的Tokens转换成一个一个的简单的表达式

    echo a constant string

    add two numbers together

    store the result of the prior expression to a variable

    echo a variable

    然后就改Compilation阶段了,它会把Tokens编译成一个个op_array, 每个op_arrayd包含如下5个部分:

    Opcode数字的标识,指明了每个op_array的操作类型,比如add , echo

    结果 存放Opcode结果

    操作数1 给Opcode的操作数

    操作数2

    扩展值1个整形用来区别被重载的操作符

    比如,我们的PHP代码会被Parsing成:

    ZEND_ECHO 'Hello World'

    ZEND_ADD ~0 1 1

    ZEND_ASSIGN !0 ~0

    ZEND_ECHO !0

    你可能会问了,我们的$a去那里了?

    这个要介绍操作数了,每个操作数都是由以下俩个部分组成:

    op_type : 为IS_CONST, IS_TMP_VAR, IS_VAR, IS_UNUSED, or IS_CV b)

    u,一个联合体,根据op_type的不同,分别用不同的类型保存了这个操作数的值(const)或者左值(var)

    而对于var来说,每个var也不一样

    IS_TMP_VAR, 顾名思义,这个是一个临时变量,保存一些op_array的结果,以便接下来的op_array使用,这种的操作数的u保存着一个指向变量表的一个句柄(整数),这种操作数一般用开头,比如0,表示变量表的0号未知的临时变量

    IS_VAR 这种就是我们一般意义上的变量了,他们以$开头表示

    IS_CV 表示ZE2.1/PHP5.1以后的编译器使用的一种cache机制,这种变量保存着被它引用的变量的地址,当一个变量第一次被引用的时候,就会被CV起来,以后对这个变量的引用就不需要再次去查找active符号表了,CV变量以!开头表示。

    这么看来,我们的$a被优化成!0了。

    更多相关内容
  • 此文主要基于《 Understanding OPcode》和 网络,根据个人的理解和修改,特记录下来 : PHP代码: <?php echo "Hello World"; $a = 1 + 1; echo $a; ?> PHP执行这段代码会经过如下4个步骤: 1. Scanning...
  • x86 opcode structure and instruction overview
  • 首先下载最新版vld扩展接下来编译安装vld扩展最后将生成的vld.so复制到extension_dir目录下然后修改php.ini文件接下来创建test.php文件,感兴趣的你可以参考下本
  • CacheTool一个清除APC/opcode缓存的类库
  • 1.什么是opcode 解释器分析代码之后,生成可以直接运行的中间代码,就称做操作码,opcode 2.解释器与编译器的区别 解释器是生成了中间代码后直接运行中间代码,运行时的控制权还是在解释器手里。 编译器则是生成了...
  • PHP语言在性能上相对于其他编译型语言来说性能算不上突出,但是使用了OPCode缓存后性能提升还是很明显的.常见的主要有Eaccelerator,XCache,APC本文主要介绍APC的使用.
  • opcode是计算机指令中的一部分,用于指定要执行的操作, 指令的格式和规范由处理器的指令规范指定。 除了指令本身以外通常还有指令所需要的操作数,可能有的指令不需要显式的操作数。 这些操作数可能是寄存器中的值...
  • 前言 鸟哥在博客中说,提高PHP 7性能的...那么什么是Opcache呢? ... Optimizer+ 将PHP代码预编译生成的脚本文件 Opcode 缓存在共享内存中供以后反复使用,从而避免了从磁盘读取代码再次编译的时间消耗。同时,它还应用了
  • Opcode.zip

    2019-06-23 13:00:07
    Opcode机器码的对应解析位图,有助于更好的去解析Opcode机器码。
  • 主要给大家介绍了关于如何使用OpCode绕过Python沙箱的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Python具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
  • PHP5.5开始内置了Zend OPcache的缓存系统,这个系统在5.2-5.4下也是可以使用的。经过测试,在php5.4下的加速性能明显,效果比5.2+ea还要好,在此推荐安装
  • Dalvik Opcode Graph based Android Malware Variants Detection using Global Topology Features
  • php opcode的反解,用于分析PHP ,逆向PHP 加密,由OPCODE转换PHP代码. WINDOWS 版本的使用: 开始,运行,CMD 进入PHP所在目录,执行: Php.exe –c php.ini 111.php 回车,即可查看:111.php 的OPCODE值. 用这个工具,可以...
  • OpCode

    2019-09-26 19:15:43
    OpCode组成: Prefixes Code ModR/M SIB Displacement Immediate 以上六个域是可选的(非必须,非线性),但Code域是必须有的;而且排列顺序也不能打乱,如果存在某域必须按照从左到右 Prefixes->Code-...

    ABOUT OPCODE

    OpCode组成:

     

    Prefixes

    Code

    ModR/M

    SIB

    Displacement

    Immediate

     

    以上六个域是可选的(非必须,非线性),但Code域是必须有的;而且排列顺序也不能打乱,如果存在某域必须按照 从左到右 

    Prefixes -> Code -> ModR/M -> SIB -> Displacement -> Immediate 排序。

     

    About Prefixes:

     

    Prefixes的几个特性:

    1. 它是唯一的一个可能出现在code之前的域。

    2. 所有的Prefixes都只有1个字节。

    3. 在一个OpCode中可能会有多个Prefixes

    4.一个OpCode中可以有多个Prefixes

    5.如果有多个Prefixes,那么它们的顺序可以打乱,不会有任何问题。

    6.如果Prefixes不能对随它之后的OpCode起作用,那么它就会被忽略。

     

      Prefixes,它们可以被划分为5个集合,分别是:

    1.Change DEFAULT operand size. (66) 

    2.Change DEFAULT address size. (67)

    3.Repeat prefixes. (F2, F3)

    4.Segment override prefixes(change DEFAULT segment). (2E, 36, 3E, 26, 64, 65)

    5.LOCK prefix. (F0)

     

    1) 66 // 切换默认的操作数的大小;如果默认的操作数大小是WORD16位),那么切换后就是DWORD32位);反之,如果默认的操作数大小是DWORD32位),那么切换后就是WORD16位)。

    让我们再来看一个特例:

     

    B0 FF    MOV AL, 0FF

    8A C1    MOV AL, CL

    看清楚了吗?现在的操作数是ALCL,加上prefix 66后会如何?

     

    66 B0 FF    MOV AL, 0FF

    66 8A C1    MOV AL, CL

    Faint!没有任何变化!

     

    为什么呢?我们可以猜测一下:也许并不是所有情况下的操作数大小都可以随意改变的。假如这个改变是不允许的,那么它就会被忽略。

     

    2)67 //切换默认的地址大小。请注意:6766的 分别在于,66改变的是默认的操作数大小,而67则是地址的大小。

    3)F2/F3   rep[F3]repe[F3]repne[F2]

    4)2E, 36, 3E, 26, 64, 65 //用来改变默认的段

    Prefix Explanation

    2E CS segment override prefix

    36 SS segment override prefix

    3E DS segment override prefix

    26 ES segment override prefix

    64 FS segment override prefix

    65 GS segment override prefix

    5)LOCK Prefix (F0)

    对于这个PrefixIntel的文档已经解释得很清楚了,不过它的具体意义对OpCode的格式学习并无任何帮助,有兴趣的读者可以在<<Intel Architecture Software Developer's Manual Volume 2: Instruction Set Reference>>3-387页看到关于它的详细解释。在OpCode的格式学习中,我们只需要知道F0表示的是助记符LOCK就足够了。

     

    ABOUT ModR/M:

    ModR/M是由ModReg/OpcodeR/M三个部分组成的。每个部分所占的bit大小为(2:3:3)

           Mod: 占最高位的672bit

         Reg/Opcode: 占中间位的353bit

           R/M: 占最低位的023bit

     

    REG && Register

    REGRegister

    000EAX

    001ECX

    010EDX

    011EBX

    100ESP

    101EBP

    110ESI

    111EDI

     

    Mod: 11  表示应该查看Mod11的那一栏

    Reg/Opcode: 111 表示的是寄存器EDI

    R/M: 001 表示的是ECX

     

     

    转载于:https://www.cnblogs.com/myntbk/p/3712509.html

    展开全文
  • BLEMESH的opcode和model id

    MODEL ID 标准的为16为,自定义的Vendor Model ID为32位

    Model GroupModel NameSIG Model ID
    GenericGeneric OnOff Server0x1000
    Generic OnOff Client0x1001
    Generic Level Server0x1002
    Generic Level Client0x1003
    Generic Default Transition Time Server0x1004
    Generic Default Transition Time Client0x1005
    Generic Power OnOff Server0x1006
    Generic Power OnOff Setup Server0x1007
    Generic Power OnOff Client0x1008
    Generic Power Level Server0x1009
    Generic Power Level Setup Server0x100A
    Generic Power Level Client0x100B
    Generic Battery Server0x100C
    Generic Battery Client0x100D
    Generic Location Server0x100E
    Generic Location Setup Server0x100F
    Generic Location Client0x1010
    Generic Admin Property Server0x1011
    Generic Manufacturer Property Server0x1012
    Generic User Property Server0x1013
    Generic Client Property Server0x1014
    Generic Property Client0x1015
    SensorsSensor Server0x1100
    Sensor Setup Server0x1101
    Sensor Client0x1102
    Time and ScenesTime Server0x1200
    Time Setup Server0x1201
    Time Client0x1202
    Scene Server0x1203
    Scene Setup Server0x1204
    Scene Client0x1205
    Scheduler Server0x1206
    Scheduler Setup Server0x1207
    Scheduler Client0x1208
    LightingLight Lightness Server0x1300
    Light Lightness Setup Server0x1301
    Light Lightness Client0x1302
    Light CTL Server0x1303
    Light CTL Setup Server0x1304
    Light CTL Client0x1305
    Light CTL Temperature Server0x1306
    Light HSL Server0x1307
    Light HSL Setup Server0x1308
    Light HSL Client0x1309
    Light HSL Hue Server0x130A
    Light HSL Saturation Server0x130B
    Light xyL Server0x130C
    Light xyL Setup Server0x130D
    Light xyL Client0x130E
    Light LC Server0x130F
    Light LC Setup Server0x1310
    Light LC Client0x1311

    OPCODE可用于每个网格模型的消息及其操作码的列表

    Server ModelMessage NameOpcode
    Generic OnOffGeneric OnOff Get0x82 0x01
    Generic OnOff Set0x82 0x02
    Generic OnOff Set Unacknowledged0x82 0x03
    Generic OnOff Status0x82 0x04
    Generic LevelGeneric Level Get0x82 0x05
    Generic Level Set0x82 0x06
    Generic Level Set Unacknowledged0x82 0x07
    Generic Level Status0x82 0x08
    Generic Delta Set0x82 0x09
    Generic Delta Set Unacknowledged0x82 0x0A
    Generic Move Set0x82 0x0B
    Generic Move Set Unacknowledged0x82 0x0C
     
    Generic Default Transition
    Time
    Generic Default Transition Time Get0x82 0x0D
    Generic Default Transition Time Set0x82 0x0E
    Generic Default Transition Time Set Unacknowledged0x82 0x0F
    Generic Default Transition Time Status0x82 0x10
    Generic Power OnOffGeneric OnPowerUp Get0x82 0x11
    Generic OnPowerUp Status0x82 0x12
    Generic Power OnOff SetupGeneric OnPowerUp Set0x82 0x13
    Generic OnPowerUp Set Unacknowledged0x82 0x14
    Generic Power LevelGeneric Power Level Get0x82 0x15
    Generic Power Level Set0x82 0x16
    Generic Power Level Set Unacknowledged0x82 0x17
    Generic Power Level Status0x82 0x18
    Generic Power Last Get0x82 0x19
    Generic Power Last Status0x82 0x1A
    Generic Power Default Get0x82 0x1B
    Generic Power Default Status0x82 0x1C
    Generic Power Range Get0x82 0x1D
    Generic Power Range Status0x82 0x1E
    Generic Power Level SetupGeneric Power Default Set0x82 0x1F
    Generic Power Default Set Unacknowledged0x82 0x20
    Generic Power Range Set0x82 0x21
    Generic Power Range Set Unacknowledged0x82 0x22
    Generic BatteryGeneric Battery Get0x82 0x23
    Generic Battery Status0x82 0x24
    Generic LocationGeneric Location Global Get0x82 0x25
    Generic Location Global Status0x40
    Generic Location Local Get0x82 0x26
    Generic Location Local Status0x82 0x27
    Generic Location SetupGeneric Location Global Set0x41
    Generic Location Global Set Unacknowledged0x42
    Generic Location Local Set0x82 0x28
    Generic Location Local Set Unacknowledged0x82 0x29
     
    Generic Manufacturer
    Property
    Generic Manufacturer Properties Get0x82 0x2A
    Generic Manufacturer Properties Status0x43
    Generic Manufacturer Property Get0x82 0x2B
    Generic Manufacturer Property Set0x44
    Generic Manufacturer Property Set Unacknowledged0x45
    Generic Manufacturer Property Status0x46
    Generic Admin PropertyGeneric Admin Properties Get0x82 0x2C
    Generic Admin Properties Status0x47
    Generic Admin Property Get0x82 0x2D
    Generic Admin Property Set0x48
    Generic Admin Property Set Unacknowledged0x49
    Generic Admin Property Status0x4A
    Generic User PropertyGeneric User Properties Get0x82 0x2E
    Generic User Properties Status0x4B
    Generic User Property Get0x82 0x2F
    Generic User Property Set0x4C
    Generic User Property Set Unacknowledged0x4D
    Generic User Property Status0x4E
    Generic Client PropertyGeneric Client Properties Get0x4F
    Generic Client Properties Status0x50
    SensorSensor Descriptor Get0x82 0x30
    Sensor Descriptor Status0x51
    Sensor Get0x82 0x31
    Sensor Status0x52
    Sensor Column Get0x82 0x32
    Sensor Column Status0x53
    Sensor Series Get0x82 0x33
    Sensor Series Status0x54
    Sensor SetupSensor Cadence Get0x82 0x34
    Sensor Cadence Set0x55
    Sensor Cadence Set Unacknowledged0x56
    Sensor Cadence Status0x57
    Sensor Settings Get0x82 0x35
    Sensor Settings Status0x58
    Sensor Setting Get0x82 0x36
    Sensor Setting Set0x59
    Sensor Setting Set Unacknowledged0x5A
    Sensor Setting Status0x5B
    TimeTime Get0x82 0x37
    Time Set0x5C
    Time Status0x5D
    Time Role Get0x82 0x38
    Time Role Set0x82 0x39
    Time Role Status0x82 0x3A
    Time Zone Get0x82 0x3B
    Time Zone Set0x82 0x3C
    Time Zone Status0x82 0x3D
    TAI-UTC Delta Get0x82 0x3E
    TAI-UTC Delta Set0x82 0x3F
    TAI-UTC Delta Status0x82 0x40
    SceneScene Get0x82 0x41
    Scene Recall0x82 0x42
    Scene Recall Unacknowledged0x82 0x43
    Scene Status0x5E
    Scene Register Get0x82 0x44
    Scene Register Status0x82 0x45
    Scene SetupScene Store0x82 0x46
    Scene Store Unacknowledged0x82 0x47
    Scene Delete0x82 0x9E
    Scene Delete Unacknowledged0x82 0x9F
    SchedulerScheduler Action Get0x82 0x48
    Scheduler Action Status0x5F
    Scheduler Get0x82 0x49
    Scheduler Status0x82 0x4A
    Scheduler SetupScheduler Action Set0x60
    Scheduler Action Set Unacknowledged0x61
    Light LightnessLight Lightness Get0x82 0x4B
    Light LightnessLight Lightness Set0x82 0x4C
    Light Lightness Set Unacknowledged0x82 0x4D
    Light Lightness Status0x82 0x4E
    Light Lightness Linear Get0x82 0x4F
    Light Lightness Linear Set0x82 0x50
    Light Lightness Linear Set Unacknowledged0x82 0x51
    Light Lightness Linear Status0x82 0x52
    Light Lightness Last Get0x82 0x53
    Light Lightness Last Status0x82 0x54
    Light Lightness Default Get0x82 0x55
    Light Lightness Default Status0x82 0x56
    Light Lightness Range Get0x82 0x57
    Light Lightness Range Status0x82 0x58
    Light Lightness SetupLight Lightness Default Set0x82 0x59
    Light Lightness Default Set Unacknowledged0x82 0x5A
    Light Lightness Range Set0x82 0x5B
    Light Lightness Range Set Unacknowledged0x82 0x5C
    Light CTLLight CTL Get0x82 0x5D
    Light CTL Set0x82 0x5E
    Light CTL Set Unacknowledged0x82 0x5F
    Light CTL Status0x82 0x60
    Light CTL Temperature Get0x82 0x61
    Light CTL Temperature Range Get0x82 0x62
    Light CTL Temperature Range Status0x82 0x63
    Light CTL Temperature Set0x82 0x64
    Light CTL Temperature Set Unacknowledged0x82 0x65
    Light CTL Temperature Status0x82 0x66
    Light CTL Default Get0x82 0x67
    Light CTL Default Status0x82 0x68
    Light CTL SetupLight CTL Default Set0x82 0x69
    Light CTL Default Set Unacknowledged0x82 0x6A
    Light CTL Temperature Range Set0x82 0x6B
    Light CTL Temperature Range Set Unacknowledged0x82 0x6C
    Light HSLLight HSL Get0x82 0x6D
    Light HSL Hue Get0x82 0x6E
    Light HSL Hue Set0x82 0x6F
    Light HSL Hue Set Unacknowledged0x82 0x70
    Light HSL Hue Status0x82 0x71
    Light HSL Saturation Get0x82 0x72
    Light HSLLight HSL Saturation Set0x82 0x73
    Light HSL Saturation Set Unacknowledged0x82 0x74
    Light HSL Saturation Status0x82 0x75
    Light HSL Set0x82 0x76
    Light HSL Set Unacknowledged0x82 0x77
    Light HSL Status0x82 0x78
    Light HSL Target Get0x82 0x79
    Light HSL Target Status0x82 0x7A
    Light HSL Default Get0x82 0x7B
    Light HSL Default Status0x82 0x7C
    Light HSL Range Get0x82 0x7D
    Light HSL Range Status0x82 0x7E
    Light HSL SetupLight HSL Default Set0x82 0x7F
    Light HSL Default Set Unacknowledged0x82 0x80
    Light HSL Range Set0x82 0x81
    Light HSL Range Set Unacknowledged0x82
    Light xyLLight xyL Get0x82 0x83
    Light xyL Set0x82 0x84
    Light xyL Set Unacknowledged0x82 0x85
    Light xyL Status0x82 0x86
    Light xyL Target Get0x82 0x87
    Light xyL Target Status0x82 0x88
    Light xyL Default Get0x82 0x89
    Light xyL Default Status0x82 0x8A
    Light xyL Range Get0x82 0x8B
    Light xyL Range Status0x82 0x8C
    Light xyL SetupLight xyL Default Set0x82 0x8D
    Light xyL Default Set Unacknowledged0x82 0x8E
    Light xyL Range Set0x82 0x8F
    Light xyL Range Set Unacknowledged0x82 0x90
    Light ControlLight LC Mode Get0x82 0x91
    Light LC Mode Set0x82 0x92
    Light LC Mode Set Unacknowledged0x82 0x93
    Light LC Mode Status0x82 0x94
    Light LC OM Get0x82 0x95
    Light LC OM Set0x82 0x96
    Light LC OM Set Unacknowledged0x82 0x97
    Light LC OM Status0x82 0x98
    Light LC Light OnOff Get0x82 0x99
    Light LC Light OnOff Set0x82 0x9A
    Light LC Light OnOff Set Unacknowledged0x82 0x9B
    Light LC Light OnOff Status0x82 0x9C
    Light LC Property Get0x82 0x9D
    Light LC Property Set0x62
    Light LC Property Set Unacknowledged0x63
    Light LC Property Status0x64
    展开全文
  • PHP获取Opcode及C源码

    2022-06-25 13:17:50
    是什么 在开始之前, 必须要先介绍一下Opcode是什么. 众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行. ...

    是什么

    在开始之前, 必须要先介绍一下Opcode是什么.

    众所周知, Java在执行的时候, 会将.java后缀的文件预先编译为.class字节码文件, JVM加载字节码文件进行解释执行. 而字节码文件存在的意义, 就是为了加速执行.

    那么PHPOpcode与之类似, 也是从.php文件到执行的过程中, 所生成的预编译中间文件.

    或者也可以这样粗鲁的理解, PHP程序是由C写的二进制程序, Opcode就是将.php文件翻译为c代码的结果.

    Opcode有什么用我们最后再说, 先让我们看一下它长什么样子

    获得

    如何获得php文件的opcode呢? 在PHP的源码中, 可以通过c函数zend_compile_string获取PHP代码解析后的Opcode. 但是我们要是为了获取Opcode得深入到c, 是在有些得不偿失. 好在, 已经有前辈做好的扩展可直接获取. 既: vld.

    vld 扩展

    安装扩展:

    # 安装扩展
    pecl install https://pecl.php.net/get/vld
    # 启用扩展. 若不是 docker, 将"extension=vld.so" 写入 php.ini 即可
    docker-php-ext-enable vld
    # 命令行查看, 确保扩展安装成功
    php -m | grep vld
    

    我们查看这段小小代码的opcode:

    <?php
    require 't.php';
    $a = 1;
    $b = $a;
    echo $a;
    var_dump($b);
    exit(0);
    

    执行如下命令可查看:

    php -d vld.active=1 -d vld.execute=0 test.php

    image-20220623215444490

    对于vld的输出结果, 这里有作者的一篇说明文章: https://derickrethans.nl/more-source-analysis-with-vld.html

    vld扩展支持的配置. php的扩展配置可以在跑脚本的时候, 通过-d参数临时修改, 也可以直接修改php.ini文件. 这里建议临时修改, 毕竟并不是所有脚本都要输出opcode.

    • vld.active: 是否输出opcode. 默认为0
    • vld.execute: 是否要运行代码. 默认为1
      • 当为0时, 不会输出require的其他文件内容.
    • vld.verbosity: 显示更详细的信息. 默认为0, 可能值为0123
    • 等等吧, 还有一些其他的配置项, 不过感觉没什么用就不列举了. 可通过命令php -r 'phpinfo();' | grep vld 查看支持的所有配置.

    phpdbg

    按理说, 这么常用的操作, 应该是带有官方工具才对的吧. 哎, 这不就来了么. phpdbgphp程序的调试器(迄今为止, 我从来没有用过. 甚至没有用过断掉调试). 但同时它也可以用来生成opcode.

    命令: phpdbg -p test.php

    image-20220623221234892

    生成结果与vld扩展基本一致.

    还可以通过opcache来生成, 不过就有些绕了, 在这里就不介绍了. 简单介绍一下这两种方式就好.

    phpdbg生成的话, 貌似只支持单文件生成(也可能是我没找到使用方法), vld则可以带着引入的文件一起打印出来.

    不过对于我们分析程序来说, phpdbg一般是够用的了.

    使用

    那么上述生成的opcode是什么意思呢? 很遗憾, 官网对opcode的解释已经找不到了, 不过zend opcode document为关键词搜索的话, 还是能搜到一大堆的. 这里就不再重复罗列其含义了了.

    我就简单说一下它有什么用吧. 总不能咱这折腾了半天, 拿到了opcode然后就没有然后了.

    opcodephp文件翻译后的中间码, 通过它, 我们大致可以知道php文件的执行过程.

    又因为php是通过c层面进行解析的, 每一条opcode都会解析为一个c函数进行执行. 对于分析源码、查找问题等等, 可直接定位到php代码在c源码级别的执行, 方便得很嘛. (类似需求我之前碰到过很多次, 比如查找sort的实现原理等等)

    所有操作码都定义在源码文件zend_vm_opcodes.h中. 既然php会根据不同的操作码, 执行不同的操作. 那么, 我们是不是就可以根据操作码, 来还原php底层执行的操作了呢? 不好意思, 可以但是很难. php通过函数zend_vm_get_opcode_handler来获取操作码对应的handle函数. 但是, 当看过源码后, 我失望了, 函数zend_vm_get_opcode_handler获取的过程是一个动态解析的过程. 也就是说, 同一个操作码, 解析后可能会是不同的函数. 啊这不就尴尬了么.

    于是, 不信邪的我, 决定通过修改PHP源码来实现. 为了方便使用, 我将其封装为了一个docker镜像, 对实现方式感兴趣的, 请移至Dockerfile. 使用方式如下(镜像的详情见: 调试镜像):

    docker run --rm -it -v `pwd`:`pwd` -w `pwd` hujingnb/php_opcode:8.1.7 php test.php

    如下所示输出结果:

    image-20220625102703295

    同时会在当前目录生成opcode.log文件, 内容如下:

    image-20220625102750935

    可查看到opcode及每一个操作码具体执行的c函数是哪个.

    其中require所对应的opcodeINCLUDE_OR_EVAL, 所执行的c函数为ZEND_INCLUDE_OR_EVAL_SPEC_CONST_HANDLER.

    总结

    至此, opcode我们也见过了, 也能将php文件转换为opcode了. 不过说实话, 这玩意在平常的开发中不能说是用不到, 可以说是根本用不到.

    它的作用我觉得还是在分析源码的时候. 可以方便的看到php代码的每一步操作, 其对应的源码执行.

    以后研究源码, 或者是对php行为感到疑惑的时候, 有这个工具就可以加速解惑的过程啦.

    调试镜像

    介绍

    此镜像是为了方便查看phpopcode及操作码对应执行的c函数. 为了方便对php源码进行分析. 通过结果, 可通过php文件直接定位到php源码的c函数.

    此镜像在vld扩展的基础上, 额外输出了:

    • 操作码对应的c执行handle函数

    此镜像基于php分支php-8.1.7, commitId 为d35e577a1bd0b35b9386cea97cddc73fd98eed6d.

    镜像地址. 这里就不说明我是怎么做的了, 感兴趣的可查看Dockerfile

    使用

    通过此镜像获得操作码简单方式:

    docker run --rm -it -v `pwd`:`pwd` -w `pwd` hujingnb/php_opcode:8.1.7 php test.php

    此命令产生如下结果:

    1. 获取php文件的opcode
    2. 获取opcode操作码对应的执行c函数. 将结果输出到当前目录的opcode.log文件中

    高级

    若需要安装扩展, 可进入镜像后执行如下操作:

    • php源码编译安装gd扩展: docker-php-ext-configure gd
    • php源码安装gd扩展: docker-php-ext-install gd
    • 启用gd扩展: docker-php-ext-enable gd
    • 通过官方库安装扩展: pecl install redis && docker-php-ext-enable redis

    环境变量:

    • PHP_SRC_DIR: 源码位置
    • PHP_INI_DIR: 配置文件位置
    • PHP_INSTALL_DIR: 安装路径

    若需要添加额外操作, 可基于此镜像进行操作, 请根据Dockerfile自行修改.

    若想要修改php源码, 可在修改后执行命令重新安装: docker-php-install

    原文地址: https://hujingnb.com/archives/836

    展开全文
  • ARM&Thumb; opcode

    2018-03-13 12:10:52
    arm和thumb指令的详细opcode,便于指令查询和熟悉指令。
  • PHP中的opcode

    2021-04-20 14:59:04
    opcode是php语言里供zend引擎执行的一种中间代码,类似java中的字节码、或者python中的字节码对象pycodeobject.对于如下的一段php代码echo “Hello World”;$a = $a + 1;echo $a;和传统的编译流程一样,zend引擎在...
  • php 开启 opcode 测试

    2021-05-03 01:00:39
    php 开启 opcode 测试,合理使用~实验环境系统信息 Linux localhost.localdomain 3.10.0-514.10.2.el7.x86_64 #1 SMP Fri Mar 3 00:04:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux内存 512M CPU 1核PHP 版本 ...
  • Opcode指令解析

    千次阅读 2019-05-27 11:11:19
    (In decimal) /digit (Opcode) (In binary) REG = AL AX EAX MM0 XMM0 0 000 CL CX ECX MM1 XMM1 1 001 DL DX EDX MM2 ...
  • Oracle opcode 汇总

    2021-05-02 07:07:46
    Layer 1 :TransactionControl - KCOCOTCT Opcode 1 : KTZFMT Opcode 2 : KTZRDH Opcode 3 : KTZARC Opcode 4 : KTZREP Layer 2 : TransactionRead- KCOCOTRD Layer 3 : TransactionUpdate- ...
  • php内核分析之opcode

    2021-03-22 21:00:13
    php内核分析之opcode在做PHP项目之前首先要对所运用的知识了解,下面是百分网小编精心为大家整理的php内核分析之opcode,希望对有需要的人有帮助,更多内容请关注应届毕业生网!...// 一个opcode的结构str...
  • opcode是什么大家都不陌生, php代码经过编译后就会形成opcode数组,zend引擎执行的就是opcode,我们看下opcode的结构体定义//zend_compile.h文件中struct_zend_op{constvoid*handler;//opcode的处理函数znode_opop1...
  • php 中间代码opcode

    2021-04-09 10:07:03
    php的词法分析、语法分析大多采用Flex/Bison处理在语法分析完成后,由zend引擎生成中间代码(使用opcache可以省略编译阶段)opcode,PHP是构建在Zend虚拟机(Zend VM)之上的。PHP的opcode就是Zend虚拟机中的指令在PHP...
  • JVM:Java指令源码opcode

    2021-09-27 16:53:44
    JVM:Java指令源码opcode 关键词 Java 字节码是沟通 JVM 与 Java 程序的桥梁 指令( opcode)由操作码和操作数组成 JVM 翻译字节码( 将 opcode + 操作数翻译成机器代码、 JIT即时编译 ) 一、 Java 程序的执行...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 40,037
精华内容 16,014
关键字:

Opcode