专业编程基础技术教程

网站首页 > 基础教程 正文

python散装笔记——57: dis 模块

ccvgpt 2025-02-14 22:26:36 基础教程 29 ℃

1: 什么是 Python 字节码?

Python 是一种混合解释器。运行程序时,它首先将程序组装成字节码,然后在 Python 解释器(也称为 Python 虚拟机)中运行。标准库中的 dis 模块可用于通过反汇编类、方法、函数和代码对象,使 Python 字节码具有人可读性。

>>> def hello():
...     print("Hello, World")
...
>>> dis.dis(hello)
2       0 LOAD_CONST        1 ('Hello, World')
        3 PRINT_ITEM
        4 PRINT_NEWLINE
        5 LOAD_CONST        0 (None)
        8 RETURN_VALUE

Python 解释器基于堆栈,使用先进后出系统。

python散装笔记——57: dis 模块

Python 汇编语言(字节码)中的每个操作码 (opcode) 都从堆栈中获取固定数量的项目,并返回堆栈中固定数量的项目。如果堆栈中没有足够的操作码,Python 解释器就会崩溃,可能没有错误信息。

2: dis 模块中的常量

EXTENDED_ARG = 145 # All opcodes greater than this have 2 operands
HAVE_ARGUMENT = 90 # All opcodes greater than this have at least 1 operands

cmp_op = ('<', '<=', '==', '!=', '>', '>=', 'in', 'not in', 'is', 'is ...
          # 比较器 id 列表。这些索引在某些操作码中用作操作数

# 这些列表中的所有操作码都有各自的操作数类型
hascompare = [107]
hasconst = [100]
hasfree = [135, 136, 137]
hasjabs = [111, 112, 113, 114, 115, 119]
hasjrel = [93, 110, 120, 121, 122, 143]
haslocal = [124, 125, 126]
hasname = [90, 91, 95, 96, 97, 98, 101, 106, 108, 109, 116]

# 操作码到 ID 的映射
opmap = {'BINARY_ADD': 23, 'BINARY_AND': 64, 'BINARY_DIVIDE': 21, 'BIN...

# 从 id 到操作码的映射
opname = ['STOP_CODE', 'POP_TOP', 'ROT_TWO', 'ROT_THREE', 'DUP_TOP', '...

3: Disassembling 模块

要反汇编 Python 模块,首先必须将其转换成 .pyc 文件(Python 编译)。为此,运行

python -m compileall .py

然后在解释器中运行

import dis
import marshal

with open(".pyc", "rb") as code_f:
  code_f.read(8) # Magic number and modification time
  code = marshal.load(code_f) # Returns a code object which can be disassembled
  dis.dis(code) # Output the disassembly

这将编译一个 Python 模块,并输出带有 dis 的字节码指令。该模块从未被导入,因此可以安全地与不信任的代码一起使用。

最近发表
标签列表