栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 面试经验 > 面试问答

我应该如何理解dis.dis的输出?

面试问答 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

我应该如何理解dis.dis的输出?

您正在尝试拆解内含源代码的字符串,但是这不支持

dis.dis
在Python
2.用字符串参数,它把字符串,如果它包含字节码(见函数
disassemble_string
dis.py
)。因此,您会看到基于将源代码误解为字节码而产生的无意义的输出。

Python 3中的情况有所不同,Python
3在反汇编之前先

dis.dis
编译字符串参数:

Python 3.2.3 (default, Aug 13 2012, 22:28:10) >>> import dis>>> dis.dis('heapq.nlargest(d,3)')  10 LOAD_NAME     0 (heapq)    3 LOAD_ATTR     1 (nlargest)    6 LOAD_NAME     2 (d)    9 LOAD_ConST    0 (3)   12 CALL_FUNCTION 2   15 RETURN_VALUE

在Python 2中,您需要先自行编译代码,然后再将其传递给

dis.dis

Python 2.7.3 (default, Aug 13 2012, 18:25:43) >>> import dis>>> dis.dis(compile('heapq.nlargest(d,3)', '<none>', 'eval'))  10 LOAD_NAME     0 (heapq)   3 LOAD_ATTR     1 (nlargest)   6 LOAD_NAME     2 (d)   9 LOAD_ConST    0 (3)  12 CALL_FUNCTION 2  15 RETURN_VALUE

这些数字是什么意思?数

1
在最左边是在从其中该字节代码被编译的源代码的行号。左列中的数字是指令在字节码中的偏移量,而右列中的数字是 opargs
。让我们看一下实际的字节码:

>>> co = compile('heapq.nlargest(d,3)', '<none>', 'eval')>>> co.co_pre.enpre('hex')'6500006a010065020064000083020053'

我们在字节码的偏移量0处找到了oparg

65
的操作码; 那么(在偏移量3处)是操作码,操作参数,以此类推。请注意,opargs的顺序为little-
endian,即数字1。未记录的模块包含一些表,这些表为您提供每个操作码的名称,并为您提供每个名称的操作码:
LOAD_NAME``0000``6a``LOAD_ATTR``0100``0100``oppre``opname``opmap

>>> oppre.opname[0x65]'LOAD_NAME'

oparg的含义取决于操作码,对于全文,您需要阅读中的CPython虚拟机的实现

ceval.c
。For
LOAD_NAME
LOAD_ATTR
oparg是
co_names
代码对象属性的索引:

>>> co.co_names('heapq', 'nlargest', 'd')

因为

LOAD_CONST
它是
co_consts
代码对象属性的索引:

>>> co.co_consts(3,)

对于

CALL_FUNCTION
,它是传递给函数的参数数目,以16位编码,低字节为普通参数的数目,高字节为关键字参数的数目。



转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/617641.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号