Python 字节码反汇编器
Python 标准库中的 dis 模块提供了许多有用的函数,用于通过反汇编将 Python 字节码分析成人类可读的形式。这有助于执行优化。字节码是解释器的特定版本实现细节。
dis() 函数
dis() 函数生成任何 Python 代码源(例如模块、类、方法、函数或代码对象)的反汇编表示形式。
>>> def hello(): print ("hello world") >>> import dis >>> dis.dis(hello) 2 0 LOAD_GLOBAL 0 (print) 3 LOAD_CONST 1 ('hello world') 6 CALL_FUNCTION 1 (1 positional, 0 keyword pair) 9 POP_TOP 10 LOAD_CONST 0 (None) 13 RETURN_VALUE
字节码分析 API 在 Bytecode 类中定义。它的构造函数返回 Bytecode 对象,该对象具有以下方法来分析字节码
Bytecode()
这是构造函数。分析对应于函数、生成器、方法、源代码字符串或代码对象的字节码。这是许多函数的便捷包装器
>>> string=dis.Bytecode(hello) >>> for x in string: print (x) Instruction(opname = 'LOAD_GLOBAL', opcode = 116, arg = 0, argval = 'print', argrepr = 'print', offset = 0, starts_line = 2, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello world', argrepr = "'hello world'", offset = 3, starts_line = None, is_jump_target = False) Instruction(opname = 'CALL_FUNCTION', opcode = 131, arg = 1, argval = 1, argrepr = '1 positional, 0 keyword pair', offset = 6, starts_line = None, is_jump_target = False) Instruction(opname = 'POP_TOP', opcode = 1, arg = None, argval = None, argrepr = '', offset = 9, starts_line = None, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = None, argrepr = 'None', offset = 10, starts_line = None, is_jump_target = False) Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 13, starts_line = None, is_jump_target = False)
code_info()
此函数返回 Python 代码对象的信息。
>>> dis.code_info(hello) "Name: hello\nFilename: <pyshell#2>\nArgument count: 0\nKw-only arguments: 0\nNumber of locals: 0\nStack size: 2\nFlags: OPTIMIZED, NEWLOCALS, NOFREE\nConstants:\n 0: None\n 1: 'hello world'\nNames:\n 0: print"
show_code()
此函数打印 Python 模块、函数或类的详细代码信息。
>>> dis.show_code(hello) Name: hello Filename: <pyshell#2> Argument count: 0 Kw-only arguments: 0 Number of locals: 0 Stack size: 2 Flags: OPTIMIZED, NEWLOCALS, NOFREE Constants: 0: None 1: 'hello world' Names: 0: print
disassemble()
此函数反汇编代码对象,并将输出分成以下几列:
每行的第一条指令的行号
当前指令,用 --> 表示
带标签的指令,用 >> 表示
指令的地址
操作码名称
操作参数,以及
括号中对参数的解释。
>>> codeInString = 'a = 5\nb = 6\nsum = a + b \ nprint("sum = ",sum)' >>> codeObejct = compile(codeInString, 'sumstring', 'exec') >>> dis.disassemble(codeObejct)
输出
1 0 LOAD_CONST 0 (5) 3 STORE_NAME 0 (a) 2 6 LOAD_CONST 1 (6) 9 STORE_NAME 1 (b) 3 12 LOAD_NAME 0 (a) 15 LOAD_NAME 1 (b) 18 BINARY_ADD 19 STORE_NAME 2 (sum) 4 22 LOAD_NAME 3 (print) 25 LOAD_CONST 2 ('sum =') 28 LOAD_NAME 2 (sum) 31 CALL_FUNCTION 2 (2 positional, 0 keyword pair) 34 POP_TOP 35 LOAD_CONST 3 (None) 38 RETURN_VALUE
get_instructions()
此函数返回提供的函数、方法、源代码字符串或代码对象中指令的迭代器。迭代器生成一系列 Instruction 命名元组,提供提供的代码中每个操作的详细信息。
>>> it=dis.get_instructions(code) >>> for i in it: print (i) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = <code object hello at 0x02A9BA70, file "<disassembly>", line 2>, argrepr = '<code object hello at 0x02A9BA70, file "<disassembly>", line 2>', offset = 0, starts_line = 2, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello', argrepr = "'hello'", offset = 3, starts_line = None, is_jump_target = False) Instruction(opname = 'MAKE_FUNCTION', opcode = 132, arg = 0, argval = 0, argrepr = '', offset = 6, starts_line = None, is_jump_target = False) Instruction(opname = 'STORE_NAME', opcode = 90, arg = 0, argval = 'hello', argrepr = 'hello', offset = 9, starts_line = None, is_jump_target = False) Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 2, argval = None, argrepr = 'None', offset = 12, starts_line = None, is_jump_target = False) Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 15, starts_line = None, is_jump_target = False)
函数信息采用元组状对象的格式,其参数如下所示:
Instruction | 字节码操作的详细信息 |
---|---|
opcode | 操作的数字代码,对应于下面列出的操作码值和 Opcode 集合中的字节码值。 |
opname | 操作的人类可读名称 |
arg | 操作的数字参数(如果有),否则为 None |
argval | 已解析的 arg 值(如果已知),否则与 arg 相同 |
argrepr | 操作参数的人类可读描述 |
offset | 操作在字节码序列中的起始索引 |
starts_line | 此操作码开始的行(如果有),否则为 None |
is_jump_target | 如果其他代码跳转到此处,则为 True,否则为 False |
广告