python 字节码死磕

- python代码编译成字节码【类似于汇编指令的中间语言】
- 字节码由python虚拟机来执行编译后的字节码
源码行号 | 指令偏移量 | 指令符号 | 指令参数 | 实际参数值
test(2,'hello')
1 0 LOAD_NAME 0 (test)
2 LOAD_CONST 0 (2)
4 LOAD_CONST 1 ('hello')
6 CALL_FUNCTION 2
8 POP_TOP
10 LOAD_CONST 2 (None)
12 RETURN_VALUE
n = n / p
1 0 LOAD_NAME 0 (n)
2 LOAD_NAME 1 (p)
4 BINARY_TRUE_DIVIDE
6 STORE_NAME 0 (n)
8 LOAD_CONST 0 (None)
10 RETURN_VALUE
def test(arg1):
num = 0
print(num, arg1)
1 0 LOAD_CONST 0 (<code object test at 0x10546c150, file "code.py", line 1>)
2 LOAD_CONST 1 ('test')
4 MAKE_FUNCTION 0
6 STORE_NAME 0 (test)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE Disassembly of <code object test at 0x10546c150, file "code.py", line 1>:
2 0 LOAD_CONST 1 (0)
2 STORE_FAST 1 (num) 3 4 LOAD_GLOBAL 0 (print)
6 LOAD_FAST 1 (num)
8 LOAD_FAST 0 (arg1). #只有LOAD_FAST ,没有 STORE_FAST
10 CALL_FUNCTION 2
12 POP_TOP
14 LOAD_CONST 0 (None)
16 RETURN_VALUE
def test(arg1):
global age
age = 20
print(age)
1 0 LOAD_CONST 0 (<code object test at 0x1056e3150, file "code.py", line 1>)
2 LOAD_CONST 1 ('test')
4 MAKE_FUNCTION 0
6 STORE_NAME 0 (test)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE Disassembly of <code object test at 0x1056e3150, file "code.py", line 1>:
3 0 LOAD_CONST 1 (20)
2 STORE_GLOBAL 0 (age) 4 4 LOAD_GLOBAL 1 (print)
6 LOAD_GLOBAL 0 (age)
8 CALL_FUNCTION 1
10 POP_TOP
12 LOAD_CONST 0 (None)
14 RETURN_VALUE
a = [1, 2]
1 0 LOAD_CONST 0 (1)
2 LOAD_CONST 1 (2)
4 BUILD_LIST 2
6 STORE_NAME 0 (a)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE //程序结束
[ x for x in range(4) if x > 2 ]
1 0 LOAD_CONST 0 (<code object <listcomp> at 0x10bffa150, file "code.py", line 1>)
2 LOAD_CONST 1 ('<listcomp>')
4 MAKE_FUNCTION 0
6 LOAD_NAME 0 (range)
8 LOAD_CONST 2 (4)
10 CALL_FUNCTION 1
12 GET_ITER
14 CALL_FUNCTION 1
16 POP_TOP
18 LOAD_CONST 3 (None)
20 RETURN_VALUE Disassembly of <code object <listcomp> at 0x10bffa150, file "code.py", line 1>:
1 0 BUILD_LIST 0 //创建 list , 为赋值给某变量,这种时候一般都是语法糖结构了
2 LOAD_FAST 0 (.0)
>> 4 FOR_ITER 16 (to 22) //开启迭代循环
6 STORE_FAST 1 (x) //局部变量x
8 LOAD_FAST 1 (x) // 导入 x
10 LOAD_CONST 0 (2) // 导入 2
12 COMPARE_OP 4 (>) // x 与 2 进行比较,比较符号为 >
14 POP_JUMP_IF_FALSE 4 // 不满足条件就跳过 “出栈“ 动作,既,continue 到 " >> 4 FOR_ITER. “ 处
16 LOAD_FAST 1 (x) // 读取满足条件的局部变量x
18 LIST_APPEND 2 // 把满足条件的x 添加到list中
20 JUMP_ABSOLUTE 4
>> 22 RETURN_VALUE //程序结束
k = {'a': 1}
1 0 LOAD_CONST 0 ('a')
2 LOAD_CONST 1 (1)
4 BUILD_MAP 1
6 STORE_NAME 0 (k)
8 LOAD_CONST 2 (None)
10 RETURN_VALUE
num = [1, 2, 3]
a = num[1:2]
b = num[0:1:1]
num[1:2] = [10, 11]
1 0 LOAD_CONST 0 (1)
2 LOAD_CONST 1 (2)
4 LOAD_CONST 2 (3)
6 BUILD_LIST 3
8 STORE_NAME 0 (num) 2 10 LOAD_NAME 0 (num)
12 LOAD_CONST 0 (1)
14 LOAD_CONST 1 (2)
16 BUILD_SLICE 2 #创建了一个切片
18 BINARY_SUBSCR #读取切片中的值
20 STORE_NAME 1 (a) #将读取切片中的值赋值给变量 a 3 22 LOAD_NAME 0 (num)
24 LOAD_CONST 3 (0)
26 LOAD_CONST 0 (1)
28 LOAD_CONST 0 (1)
30 BUILD_SLICE 3
32 BINARY_SUBSCR
34 STORE_NAME 2 (b) 4 36 LOAD_CONST 4 (10)
38 LOAD_CONST 5 (11)
40 BUILD_LIST 2
42 LOAD_NAME 0 (num)
44 LOAD_CONST 0 (1)
46 LOAD_CONST 1 (2)
48 BUILD_SLICE 2
50 STORE_SUBSCR
52 LOAD_CONST 6 (None)
54 RETURN_VALUE
i = 0
while i < 10:
i += 1
1 0 LOAD_CONST 0 (0)
2 STORE_NAME 0 (i) 2 4 SETUP_LOOP 20 (to 26) // 循环开始处,26表示循环结束点
>> 6 LOAD_NAME 0 (i) // “>>" 表示循环切入点
8 LOAD_CONST 1 (10)
10 COMPARE_OP 0 (<)
12 POP_JUMP_IF_FALSE 24 3 14 LOAD_NAME 0 (i)
16 LOAD_CONST 2 (1)
18 INPLACE_ADD
20 STORE_NAME 0 (i)
22 JUMP_ABSOLUTE 6 // 逻辑上,循环在此处结束
>> 24 POP_BLOCK
>> 26 LOAD_CONST 3 (None)
28 RETURN_VALUE
num = 0
for i in range(5):
num += i
对应的字节码
1 0 LOAD_CONST 0 (0)
2 STORE_NAME 0 (num) 2 4 SETUP_LOOP 24 (to 30) //开始循环
6 LOAD_NAME 1 (range)
8 LOAD_CONST 1 (5)
10 CALL_FUNCTION 1 //调用range 函数
12 GET_ITER //获取迭代 range 的 iter
>> 14 FOR_ITER 12 (to 28) //开始进行 range 的迭代
16 STORE_NAME 2 (i) 3 18 LOAD_NAME 0 (num)
20 LOAD_NAME 2 (i)
22 INPLACE_ADD
24 STORE_NAME 0 (num)
26 JUMP_ABSOLUTE 14
>> 28 POP_BLOCK
>> 30 LOAD_CONST 2 (None)
32 RETURN_VALUE
num = 20
if num < 10:
print('lt 10')
elif num > 10:
print('gt 10')
else:
print('eq 10')
1 0 LOAD_CONST 0 (20)
2 STORE_NAME 0 (num) 2 4 LOAD_NAME 0 (num)
6 LOAD_CONST 1 (10)
8 COMPARE_OP 0 (<)
10 POP_JUMP_IF_FALSE 22 3 12 LOAD_NAME 1 (print)
14 LOAD_CONST 2 ('lt 10')
16 CALL_FUNCTION 1
18 POP_TOP
20 JUMP_FORWARD 26 (to 48) 4 >> 22 LOAD_NAME 0 (num)
24 LOAD_CONST 1 (10)
26 COMPARE_OP 4 (>)
28 POP_JUMP_IF_FALSE 40 5 30 LOAD_NAME 1 (print)
32 LOAD_CONST 3 ('gt 10')
34 CALL_FUNCTION 1
36 POP_TOP
38 JUMP_FORWARD 8 (to 48) 7 >> 40 LOAD_NAME 1 (print)
42 LOAD_CONST 4 ('eq 10')
44 CALL_FUNCTION 1
46 POP_TOP
>> 48 LOAD_CONST 5 (None)
50 RETURN_VALUE
参考资料:
python 字节码死磕的更多相关文章
- JAVA NIO 简介 (netty源码死磕1.1)
[基础篇]netty 源码死磕1.1: JAVA NIO简介 1. JAVA NIO简介 Java 中 New I/O类库 是由 Java 1.4 引进的异步 IO.由于之前老的I/O类库是阻塞I/ ...
- Java NIO Buffer(netty源码死磕1.2)
[基础篇]netty源码死磕1.2: NIO Buffer 1. Java NIO Buffer Buffer是一个抽象类,位于java.nio包中,主要用作缓冲区.Buffer缓冲区本质上是一块可 ...
- Python 字节码是什么
了解 Python 字节码是什么,Python 如何使用它来执行你的代码,以及知道它是如何帮到你的. 如果你曾经编写过 Python,或者只是使用过 Python,你或许经常会看到 Python 源代 ...
- 浮生半日:探究Python字节码
好吧!“人生苦短,请用Python”,作为python爱好者以及安全从业者,而且最近也碰到了一些这方面的问题,懂点python字节码还是很有必要的. Python是一门解释性语言,它的具体工作流程如下 ...
- Netty环境搭建 (源码死磕2)
[正文]netty源码 死磕2: 环境搭建 本小节目录 1. Netty为什么火得屌炸天? 1.1. Netty是什么? 1.2. Netty火到什么程度呢? 1.3. Netty为什么这么火? 2 ...
- EventLoop(netty源码死磕4)
精进篇:netty源码 死磕4-EventLoop的鬼斧神工 目录 1. EventLoop的鬼斧神工 2. 初识 EventLoop 3. Reactor模式回顾 3.1. Reactor模式的组 ...
- Pipeline模式(netty源码死磕6)
精进篇:netty源码死磕6 巧夺天工--Pipeline模式揭秘 1. 巧夺天工--Pipeline模式揭秘 1.1. Pipeline模式简介 管道的发名者叫,Malcolm Douglas M ...
- ChannelHandler揭秘(Netty源码死磕5)
精进篇:netty源码死磕5 揭开 ChannelHandler 的神秘面纱 目录 1. 前言 2. Handler在经典Reactor中的角色 3. Handler在Netty中的坐标位置 4. ...
- Python逆向(五)—— Python字节码解读
一.前言 前些章节我们对python编译.反汇编的原理及相关模块已经做了解读.读者应该初步掌握了通过反汇编获取python程序可读字节码的能力.python逆向或者反汇编的目的就是在没有源码的基础上, ...
随机推荐
- CodeMixer工具,完美替代ChaosTool,iOS添加垃圾代码工具,代码混淆工具,代码生成器,史上最好用的垃圾代码添加工具,自己开发的小工具
新工具 ProjectTool 已上线 这是一款快速写白包工具,秒级别写H5游戏壳包,可视化操作,极易使用,支持Swift.Objecive-C双语言 扣扣交流群:811715780 进入 Proje ...
- Python-操作XML文件
一.python对XML文件的操作 目录 1.xml 创建 2.xml 数据查询 3.xml 数据修改 4.xml 数据删除 二. 1.xml 创建 import xml.etree.ElementT ...
- angular的性能分析 -随记
$watch 的实现原理和性能分析 只有双向绑定的 scope 才会被加入$watch队列,或者手动绑定$watch的$scope 所有放在 $scope 中的变量或函数都被加入到了$watch队列当 ...
- Js的new运算符
new运算符 在JavaScript中,new是一个语法糖,可以简化代码的编写,可以批量创建对象实例. 语法糖Syntactic sugar,指计算机语言中添加的某种语法,这种语法对语言的功能并没有影 ...
- Mysql数据库设置权限
这里使用cmd窗口进行权限设置. 以管理员账号连接数据库 创建数据库 create database 数据库名字 default charset=utf8; 查看用户 select user,host ...
- 使用Jenkins与Docker持续集成与发布NetCore项目(实操篇)
使用Jenkins与Docker持续集成与发布NetCore项目(教程一) 原文地址:https://www.cnblogs.com/Jackyye/p/12588182.html 基本环境 该教程的 ...
- 北邮OJ103.反转单词 c++/java
103. 反转单词 时间限制 1000 ms 内存限制 65536 KB 题目描述 给出一句英文句子(只由大小写字母和空格组成,不含标点符号,也不会出现连续的空格),请将其中的所有单词顺序翻转 输入格 ...
- 01.为什么要学习Go语言
为什么互联网世界需要Go语言 世界上已经有太多太多的编程语言了,为什么又出来一个Go语言? 硬件限制:摩尔定律已然失效 摩尔定律:当价格不变时,集成电路上可容纳的元器件的数目,约每隔18-24个月便会 ...
- python3.4连接mysql数据库的方法
python3.4连接mysql数据库的方法 发布时间:2014-08-04编辑:www.jbxue.com 本文介绍了python3.4连接mysql数据库的方法,在python3.4中不能用mys ...
- 运行redis数据库
启动redis服务器:redis-server /usr/local/redis-5.0.5/etc/redis.conf 关闭: redis-cli shutdown启动客户端:进入bin文件夹,输 ...