Pra*_*hal 17 python bytecode python-2.7
我在理解Python的字节码及其dis模块时遇到了很多困难.
import dis
def func():
x = 1
dis.dis(func)
Run Code Online (Sandbox Code Playgroud)
在解释器中输入上面的代码会产生以下输出:
0 LOAD_CONST 1(1)
3 STORE_FAST 0(x)
6 LOAD_CONST 0(NONE)
9 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
例如:
是什么意思LOAD_CONST,STORE_FAST和喜欢的数字0,3,6和9?
我将非常感谢您可以找到此信息的特定资源.
Mar*_*ers 36
字节码前面的数字是原始二进制字节码的偏移量:
>>> func.__code__.co_code
'd\x01\x00}\x00\x00d\x00\x00S'
Run Code Online (Sandbox Code Playgroud)
一些字节码带有影响每个字节码工作方式的附加信息(参数),偏移量告诉您在字节流中找到字节码的位置.
例如,LOAD_CONST字节码(ASCII d,十六进制64)之后是两个附加字节,用于编码对与字节码相关的常量的引用.结果,STORE_FAST操作码(ASCII },十六进制7D)在索引3处找到.
该dis模块文件列出了每个指令的意思.因为LOAD_CONST,它说:
推
co_consts[consti]到堆栈上.
它指的co_consts是始终与代码对象一起出现的结构; 编译器构造:
>>> func.__code__.co_consts
(None, 1)
Run Code Online (Sandbox Code Playgroud)
操作码从该结构加载索引1(字节码中的01 00字节编码为1),并dis为您查找; 这是价值1.
下一条指令STORE_FAST描述为:
将TOS存入当地
co_varnames[var_num].
这里TOS指的是Top Of Stack; 请注意,LOAD_CONST只是把东西推到了堆栈上,1值.co_varnames是另一种结构; 它引用局部变量名,操作码引用索引0:
>>> func.__code__.co_varnames
('x',)
Run Code Online (Sandbox Code Playgroud)
dis看起来也是这样,你在代码中使用的名字是x.因此,这个操作码存储1到x.
另一个从索引0 LOAD_CONST加载None到堆栈,然后是RETURN_VALUE:
返回TOS到函数的调用者.
所以这条指令占据了堆栈的顶部(带有None常量)并从这个代码块返回.None是没有显式return语句的函数的缺省返回值.
你从dis输出中省略了一些东西,行号:
>>> dis.dis(func)
2 0 LOAD_CONST 1 (1)
3 STORE_FAST 0 (x)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
Run Code Online (Sandbox Code Playgroud)
注意2第一行; 这是原始源中包含用于这些指令的Python代码的行号.Python代码对象具有co_lnotab和co_firstlineno属性,可以将字节码映射回原始源中的行号.dis在显示反汇编时为您执行此操作.
| 归档时间: |
|
| 查看次数: |
7583 次 |
| 最近记录: |