About DIS:
Doc:http://docs.python.org/2/library/dis.html
About. PYc
The. PYc file is a compiled binary file of. py files, which is a cross-platform, byte code (byte code) executed by the virtual machine.
After the version of Python is compiled. The contents of the PYc are different.
Doc:http://docs.python.org/2/tutorial/modules.html#compiled-python-files
Sample code:
| The code is as follows |
Copy Code |
dis_list_slice.py A = [1, 2, 3] b = A c = a[1:] d = [y for x in a] a[:] = [x for x in a] |
Run:
| The code is as follows |
Copy Code |
| python-m Dis dis_list_slice.py Output: 1 0 load_const 0 (1) 3 Load_const 1 (2) 6 Load_const 2 (3) 9 Build_list 3 Store_name 0 (a) 2 Load_name 0 (a) 1 (b) store_name 3 Load_name 0 (a) Load_const 0 (1) Slice+1 Store_name 2 (c) 4 Build_list 0 Load_name 0 (a) Panax Get_iter >> For_iter (to 53) Store_name 3 (x) Load_name 4 (Y) 2 List_append 38 Jump_absolute >> Store_name 5 (d) 5 Build_list 0 Load_name 0 (a) Get_iter >> For_iter (to 78) Store_name 3 (x) Load_name 3 (x) 2 List_append Jump_absolute 63 >> Load_name 0 (a) Bayi store_slice+0 Load_const 3 (None) Return_value |
Compile:
Let's take a look at the real byte code of a = [1,2,3]
| The code is as follows |
Copy Code |
>>> CO = compile (' a=[1,2,3] ', ' <none> ', ' exec ') >>> co.co_code.encode (' hex ') ' 6400006401006402006703005a00006500005a010064030053 ' (a hexadecimal string) |
Interpretation:
First line:
| The code is as follows |
Copy Code |
1 0 load_const 0 (1)
|
The first column 1 represents the compiled bytecode for the first line of the source code, which executes a = [1, 2, 3]:
| The code is as follows |
Copy Code |
0 Load_const 0 (1) 3 Load_const 1 (2) 6 Load_const 2 (3) 9 Build_list 3 Store_name 0 (a)
|
The first 0 on the left represents the instruction's offset (offset), which reads offset = 0 from the byte code to the top two digits 64
Operation code (opcode) is Load_const
Here the 64 and Load_const are one by one corresponding,
| The code is as follows |
Copy Code |
>>> Import opcode >>> Opcode.opname[0x64] ' Load_const ' |
What do you think of here?
Yes, we can encrypt the code by modifying the opcode.
Operation Instruction Collection:
Http://docs.python.org/2/library/dis.html#python-bytecode-instructions
Load_const to the right of this 0 represents Oparg, read from the byte code is: 0000
Next read two bits from offset = 3:64,opcode is Load_const,oparg 0100, that is: 1
Continue, read two bits from offset = 4:64,opcode is Load_const,oparg 0200, that is: 2
The oparg here is the small end sequence (Little-endian).
About big-endian and small-end order:
Http://zh.wikipedia.org/wiki/%E5%AD%97%E8%8A%82%E5%BA%8F
Note: The meaning of oparg depends on opcode
For example: For Load_name and Load_attr, Oparg represents the subscript in Co_names.
Reference the byte code in the second line of the Dis.dis output source code
| The code is as follows |
Copy Code |
2 Load_name 0 (a) 1 (b) store_name >>> CO = compile (' a=[1,2,3]; B=a ', ' <none> ', ' exec ') >>> Co.co_names (' A ', ' B ') >>> co.co_code.encode (' hex ') ' 6400006401006402006703005a00006500005a010064030053′ >>> OPCODE.OPNAME[0X65] ' Load_name ' |
The oparg is 0000, which is 0, representing the data labeled 0 in Co_names, which is a.
====================================================
If there is any wrong place, please point out.