基本的Python反汇编理解

2024-03-29 07:00:42 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python文件:

$ cat main.py 
def foo():
    x = 10
    y = 20
    return x+y

foo()

python反汇编如下:

$ python -m dis main.py 
  1           0 LOAD_CONST               0 (<code object foo at 0x109a933b0, file "main.py", line 1>)
              3 MAKE_FUNCTION            0
              6 STORE_NAME               0 (foo)

  6           9 LOAD_NAME                0 (foo)
             12 CALL_FUNCTION            0
             15 POP_TOP             
             16 LOAD_CONST               1 (None)
             19 RETURN_VALUE 

以下是我的问题:

1)反汇编中,1表示main.py中的行号,LOAD_CONST表示可读格式的操作码。在操作码后面的0的大部分是什么,有时是(foo)的引用?你知道吗

2)看起来python加载函数名foo,然后调用操作码CALL_FUNCTION。从LOAD_CONST->;STORE_NAME在堆栈/堆中发生的事情。python在后台记录了什么(请尽量低级别,欢迎指向CPython源代码)?你知道吗

我在https://docs.python.org/2/library/dis.html上看到STORE_NAME

STORE_NAME(namei)

Implements name = TOS. namei is the index of name in the attribute co_names of the code object. The compiler tries to use STORE_FAST or STORE_GLOBAL if possible.

然而,除了我们正在做类似于foo = Top Of Stack的事情之外,我并不清楚这一点。那么foo实际上就是co_name中作为co_name[namei]的东西。如果我们进入LOAD_NAME,它会把一些东西从co_name带到TOS。什么是co_name(堆分配的unordered_mapdict)?你知道吗

我觉得我在挖一个越来越深的洞,我想我应该退后一步,看看社区能提供什么,然后再继续。你知道吗

更新:现在我想起来了,因为我们正在做类似于co_name[namei]和if namei的事情。co_name仅仅是一个内存管理的数组吗?你知道吗


Tags: thestorenamepyfoomainloadfunction
1条回答
网友
1楼 · 发布于 2024-03-29 07:00:42

Jason harper的评论解释了你的前两个问题。但换一种说法,操作码名称后面的数字是它们的参数,括号中的东西表示这些参数实际指的是什么。事实证明,大多数操作码只接受一个参数,对于您的特定情况,所有参数都被索引为0。你知道吗

在你的另一个问题上,如果有意义的话,LOAD\u NAME实际上是按名称加载。它将函数foo推送到TOS上,这样CALL\u函数就知道要调用什么。你知道吗

Python将名称存储在名为co_names的元组中,并进一步维护locals字典,即f_locals(在Python中可通过locals()访问)。加载名称在co_names中的特定索引处获取名称,然后在locals中查找。常量直接存储在另一个元组中,并以数字索引。你知道吗

至于代码引用,请参考CPython发行版中的$PYPATH/Python/ceval.c,或者直接在GitHub上查看。你知道吗

相关问题 更多 >