avatar

python-bytecode

python-bytecode

1
官方文档:https://docs.python.org/2/library/dis.html

栈基本操作

TOS
TOS1
TOS2
  • LOAD_NAME

    压栈

    1
    2
    3
    4
    LOAD_GLOBAL:全局变量
    LOAD_FAST:局部变量
    LOAD_CONST:常量
    LOAD_ATTR:对象中的属性
  • POP_TOP

    1
    pop
  • ROT_TWO

    1
    TOS1,TOS1互换
  • ROT_THREE

    1
    2
    栈顶三元素循环位移
    1->3
  • ROT_FOUR

    1
    2
    栈顶四元素循环位移
    1->4
  • DUP_TOP

    1
    复制栈顶元素压栈
  • DUP_TOPX(count)

    1
    复制栈顶count个元素再按原顺序压栈 count范围[1,5]

UNARY

栈顶元素弹出去,运算后压栈

  • UNARY_NEGATIVE

    取负

    1
    TOS = -TOS
  • UNARY_NOT

    逻辑取反

    1
    TOS = not TOS
  • UNARY_INVERT

    按位取反

    1
    TOS = ~ TOS

BINARY

栈顶两元素弹出去,运算后压栈

  • BINARY_ADD

    加法

    1
    TOS = TOS1 + TOS
  • BINARY_SUBTRACT

    减法

    1
    TOS = TOS1 - TOS
  • BINARY_MULTIPLY

    乘法

    1
    TOS = TOS1 * TOS
  • BINARY_DIVIDE

    除法

    1
    TOS = TOS1 / TOS
  • BINARY_MODULO

    取模

    1
    TOS = TOS1 % TOS
  • BINARY_POWER

    幂运算

    1
    TOS = TOS1 ** TOS
  • BINARY_LSHIFT

    左移

    1
    TOS = TOS1 << TOS
  • BINARY_RSHIFT

    右移

    1
    TOS = TOS1 >> TOS
  • BINARY_AND

    1
    TOS = TOS1 & TOS
  • BINARY_OR

    1
    TOS = TOS1 | TOS
  • BINARY_XOR

    异或

    1
    TOS = TOS1 ^ TOS
  • BINARY_SUBSCR

    索引

    1
    TOS = TOS1[TOS]

INPLACE

栈顶两元素弹出去,运算后压栈

1
2
3
4
5
def test(a):
a +=1
a = a + 1

dis.dis(test)
1
2
3
4
5
6
7
8
9
10
11
6           0 LOAD_FAST                0 (a)
3 LOAD_CONST 1 (1)
6 INPLACE_ADD
7 STORE_FAST 0 (a)

7 10 LOAD_FAST 0 (a)
13 LOAD_CONST 1 (1)
16 BINARY_ADD
17 STORE_FAST 0 (a)
20 LOAD_CONST 0 (None)
23 RETURN_VALUE

BUILD

  • BUILD_CLASS

    1
    利用当前栈上信息创建类
  • BUILD_TUPLE(count)

    1
    从栈顶取count个元素,创建一个tuple对象压栈
  • BUILD_LIST(count)

    1
    从栈顶取count个元素,创建一个list对象压栈
  • BUILD_SET(count)

    1
    从栈顶取count个元素,创建一个set对象压栈
  • BUILD_MAP(count)

    1
    从栈顶取count个元素,创建一个map对象压栈
  • BUILD_SLICE

    1
    创建一个SLICE对象,保存start,stop,step三个参数

SLICE

  • SLICE+0

    1
    2
    def test(a):
    a[:]
    1
    2
    3
    4
    5
    6           0 LOAD_FAST                0 (a)
    3 SLICE+0
    4 POP_TOP
    5 LOAD_CONST 0 (None)
    8 RETURN_VALUE
  • SLICE+1

    1
    2
    3
    4
    def test(a):
    a[1:]

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    6           0 LOAD_FAST                0 (a)
    3 LOAD_CONST 1 (1)
    6 SLICE+1
    7 POP_TOP
    8 LOAD_CONST 0 (None)
    11 RETURN_VALUE
  • SLICE+2

    1
    2
    3
    4
    def test(a):
    a[:1]

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    6           0 LOAD_FAST                0 (a)
    3 LOAD_CONST 1 (1)
    6 SLICE+2
    7 POP_TOP
    8 LOAD_CONST 0 (None)
    11 RETURN_VALUE
  • SLICE+3

    1
    2
    3
    4
    def test(a):
    a[1:2]

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    7
    6           0 LOAD_FAST                0 (a)
    3 LOAD_CONST 1 (1)
    6 LOAD_CONST 2 (2)
    9 SLICE+3
    10 POP_TOP
    11 LOAD_CONST 0 (None)
    14 RETURN_VALUE
  • BUILD_SLICE

    1
    2
    3
    4
    def test(a):
    a[1:2:3]

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    6           0 LOAD_FAST                0 (a)
    3 LOAD_CONST 0 (None)
    6 LOAD_CONST 0 (None)
    9 LOAD_CONST 1 (3)
    12 BUILD_SLICE 3
    15 BINARY_SUBSCR
    16 POP_TOP
    17 LOAD_CONST 0 (None)
    20 RETURN_VALUE

STORE

栈顶弹出去赋值

1
2
3
4
def test(a):
a = 1

dis.dis(test)
1
2
3
4
6           0 LOAD_CONST               1 (1)
3 STORE_FAST 0 (a)
6 LOAD_CONST 0 (None)
9 RETURN_VALUE
1
2
3
STORE_GLOBAL:全局变量
STORE_FAST:局部变量
STORE_ATTR:对象中的属性

DELETE

删除

  • DELETE_NAME

    1
    2
    3
    4
    def test(a):
    del a

    dis.dis(test)
    1
    2
    3
    6           0 DELETE_FAST              0 (a)
    3 LOAD_CONST 0 (None)
    6 RETURN_VALUE
    1
    2
    3
    4
    DELETE_GLOBAL:全局变量
    DELETE_FAST:局部变量
    DELETE_ATTR:对象中的属性
    DELETE_SLICE+():SLICE

跳转

  • COMPARE_OP(op)

    对栈顶的两个元素做op指定的比较操作,结果压栈

    1
    2
    3
    def test(a,b):
    a>b
    dis.dis(test)
    1
    2
    3
    4
    5
    6
    6           0 LOAD_FAST                0 (a)
    3 LOAD_FAST 1 (b)
    6 COMPARE_OP 4 (>)
    9 POP_TOP
    10 LOAD_CONST 0 (None)
    13 RETURN_VALUE
  • POP_JUMP_IF_TRUE(target)

    栈顶弹出,如果为true跳转到target

    1
    2
    3
    4
    5
    def test(a,b):
    if not a>b:
    pass

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    7
    8
    6           0 LOAD_FAST                0 (a)
    3 LOAD_FAST 1 (b)
    6 COMPARE_OP 4 (>)
    9 POP_JUMP_IF_TRUE 15

    7 12 JUMP_FORWARD 0 (to 15)
    >> 15 LOAD_CONST 0 (None)
    18 RETURN_VALUE
  • POP_JUMP_IF_FALSE(target)

    栈顶弹出,如果为false跳转到target

    1
    2
    3
    4
    5
    def test(a,b):
    if a>b:
    pass

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    7
    8
    6           0 LOAD_FAST                0 (a)
    3 LOAD_FAST 1 (b)
    6 COMPARE_OP 4 (>)
    9 POP_JUMP_IF_FALSE 15

    7 12 JUMP_FORWARD 0 (to 15)
    >> 15 LOAD_CONST 0 (None)
    18 RETURN_VALUE
  • JUMP_IF_TRUE_OR_POP(target)

    1
    如果栈顶是true跳转到target,保留栈顶。否则栈顶弹出
  • JUMP_IF_FALSE_OR_POP

    1
    如果栈顶是false跳转到target,保留栈顶。否则栈顶弹出
  • JUMP_FORWARD(x)

    1
    向前跳转x字节

循环

  • for 循环

    1
    2
    3
    4
    5
    def test(a):
    for i in range(10):
    pass

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    6           0 SETUP_LOOP              20 (to 23)
    3 LOAD_GLOBAL 0 (range)
    6 LOAD_CONST 1 (10)
    9 CALL_FUNCTION 1
    12 GET_ITER
    >> 13 FOR_ITER 6 (to 22)
    16 STORE_FAST 1 (i)

    7 19 JUMP_ABSOLUTE 13
    >> 22 POP_BLOCK
    >> 23 LOAD_CONST 0 (None)
    26 RETURN_VALUE
  • while 循环

    1
    2
    3
    4
    5
    def test(a):
    while True:
    pass

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    7
    8
    6           0 SETUP_LOOP              10 (to 13)
    >> 3 LOAD_GLOBAL 0 (True)
    6 POP_JUMP_IF_FALSE 12

    7 9 JUMP_ABSOLUTE 3
    >> 12 POP_BLOCK
    >> 13 LOAD_CONST 0 (None)
    16 RETURN_VALUE
  • GET_ITER

    1
    取迭代器
  • BREAK_LOOP

    1
    2
    break
    取pytry_block中的handler获取循环结束后的下一条指令地址,跳出循环

函数调用

  • CALL_FUNCTION

    调用函数,调用前将pyfuntionobject和实参压栈

    1
    2
    3
    4
    5
    def test(a,b,c):
    pass
    def test2():
    test(1,2,3)
    dis.dis(test2)
    1
    2
    3
    4
    5
    6
    7
    8
    8           0 LOAD_GLOBAL              0 (test)
    3 LOAD_CONST 1 (1)
    6 LOAD_CONST 2 (2)
    9 LOAD_CONST 3 (3)
    12 CALL_FUNCTION 3
    15 POP_TOP
    16 LOAD_CONST 0 (None)
    19 RETURN_VALUE
    1
    2
    3
    4
    def test(a,b):
    dis.dis(a)

    dis.dis(test)
    1
    2
    3
    4
    5
    6
    7
    6           0 LOAD_GLOBAL              0 (dis)
    3 LOAD_ATTR 0 (dis)
    6 LOAD_FAST 0 (a)
    9 CALL_FUNCTION 1
    12 POP_TOP
    13 LOAD_CONST 0 (None)
    16 RETURN_VALUE

返回值

  • RETURN_VALUE

    1
    栈顶元素作为返回值

打印

  • PRINT_ITEM

    1
    打印栈顶元素到标准输出
  • PRINT_NEWLINE

    1
    打印回车到标准输出
    1
    2
    3
    4
    def test(a):
    print(a)

    dis.dis(test)
    1
    2
    3
    4
    5
    6           0 LOAD_FAST                0 (a)
    3 PRINT_ITEM
    4 PRINT_NEWLINE
    5 LOAD_CONST 0 (None)
    8 RETURN_VALUE

NOP

  • NOP

    1
    nop
Author: L0x1c
Link: https://l0x1c.github.io/2020/01/26/2020-01-26/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Donate
  • 微信
    微信
  • 支付寶
    支付寶