如何读取python字节码? [英] How to read python bytecode?

查看:45
本文介绍了如何读取python字节码?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在理解Python的字节码及其 dis 模块时遇到很多困难。

I am having a lot of difficulty understanding Python's bytecode and its dis module.

import dis
def func():
   x = 1
dis.dis(func)

上面的代码在解释器中键入时会产生以下输出:

The above code when typed in the interpreter produces the following output:

    0 LOAD_CONST                  1(1)
    3 STORE_FAST                  0(x)
    6 LOAD_CONST                  0(NONE)
    9 RETURN_VALUE

例如:

LOAD_CONST STORE_FAST 以及 0 3 之类的数字, 6 9

What is the meaning of LOAD_CONST, STORE_FAST and the numbers like 0, 3, 6 and 9?

特定资源,

推荐答案

字节码之前的数字会偏移到原始二进制字节码中:

The numbers before the bytecodes are offsets into the original binary bytecodes:

>>> func.__code__.co_code
'd\x01\x00}\x00\x00d\x00\x00S'

某些字节码带有附加信息(参数),这些信息会影响每个字节码的工作方式,偏移量会告诉您在字节流中字节流中的哪个位置。

Some bytecodes come with additional information (arguments) that influence how each bytecode works, the offset tells you at what position in the bytestream the bytecode was found.

LOAD_CONST 字节码(ASCII d ,十六进制64)之后是另外两个字节,例如,引用与字节码关联的常数。结果,在索引3处找到 STORE_FAST 操作码(ASCII } ,十六进制7D)。

The LOAD_CONST bytecode (ASCII d, hex 64) is followed by two additional bytes encoding a reference to a constant associated with the bytecode, for example. As a result, the STORE_FAST opcode (ASCII }, hex 7D) is found at index 3.

dis 模块文档列出了每条指令的含义。对于 LOAD_CONST ,它说:


co_consts [ consti] 放入堆栈。

指的是 co_consts 始终与代码对象一起出现的结构;编译器构造为:

which refers to the co_consts structure that is always present with a code object; the compiler constructs that:

>>> func.__code__.co_consts
(None, 1)

操作码从中加载索引1结构(字节码中的01 00字节编码为1),并且 dis 会为您查找;它是值 1

The opcode loads index 1 from that structure (the 01 00 bytes in the bytecode encode a 1), and dis has looked that up for you; it is the value 1.

下一条指令 STORE_FAST 描述为:

The next instruction, STORE_FAST is described as:


将TOS存储到本地 co_varnames [var_num]

此处 TOS 指的是堆栈顶部;请注意, LOAD_CONST 只是推入堆栈,即 1 值。 co_varnames 是另一种结构;它引用了局部变量名,操作码引用了索引0:

Here TOS refers to Top Of Stack; note that the LOAD_CONST just pushed something onto the stack, the 1 value. co_varnames is another structure; it references local variable names, the opcode references index 0:

>>> func.__code__.co_varnames
('x',)

dis 也在查找,您在代码中使用的名称是 x 。因此,此操作码将 1 存储到 x 中。

dis looked that up too, and the name you used in your code is x. Thus, this opcode stored 1 into x.

另一个 LOAD_CONST 从索引0将 None 加载到堆栈中,后跟 RETURN_VALUE

Another LOAD_CONST loads None onto the stack from index 0, followed by RETURN_VALUE:


使用TOS返回到函数的调用者。

Returns with TOS to the caller of the function.

因此,该指令占据了堆栈的顶部(具有 None 常量)并从此代码块返回。 是没有显式 return 语句的函数的默认返回值。

so this instruction takes the top of the stack (with the None constant) and returns from this code block. None is the default return value for functions without an explicit return statement.

您从 dis 输出中省略了一些内容,行号为:

You omitted something from the dis output, the line numbers:

>>> dis.dis(func)
  2           0 LOAD_CONST               1 (1)
              3 STORE_FAST               0 (x)
              6 LOAD_CONST               0 (None)
              9 RETURN_VALUE        

请注意第一行 2 ;这是原始来源中的行号,其中包含用于这些说明的Python代码。 Python代码对象具有 co_lnotab co_firstlineno 属性,可让您将字节码映射回原始源中的行号。 dis 在显示反汇编时为您执行此操作。

Note the 2 on the first line; that's the line number in the original source that contains the Python code that was used for these instructions. Python code objects have co_lnotab and co_firstlineno attributes that let you map bytecodes back to line numbers in the original source. dis does this for you when displaying a disassembly.

这篇关于如何读取python字节码?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆