Computer >> คอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Python

Disassembler สำหรับ Python bytecode


โมดูล dis ในไลบรารีมาตรฐาน Python มีฟังก์ชันต่างๆ ที่เป็นประโยชน์สำหรับการวิเคราะห์ Python bytecode โดยแยกส่วนประกอบให้อยู่ในรูปแบบที่มนุษย์อ่านได้ ซึ่งช่วยในการเพิ่มประสิทธิภาพ Bytecode เป็นรายละเอียดการใช้งานเฉพาะเวอร์ชันของล่าม

ฟังก์ชัน dis()

ฟังก์ชัน dis() สร้างการแสดงที่ถอดประกอบของซอร์สโค้ด Python เช่น โมดูล คลาส เมธอด ฟังก์ชัน หรืออ็อบเจกต์โค้ด

>>> def hello():
print ("hello world")
>>> import dis
>>> dis.dis(hello)
2    0 LOAD_GLOBAL 0 (print)
     3 LOAD_CONST 1 ('hello world')
     6 CALL_FUNCTION 1 (1 positional, 0 keyword pair)
     9 POP_TOP
     10 LOAD_CONST 0 (None)
     13 RETURN_VALUE

API การวิเคราะห์ Bytecode ถูกกำหนดในคลาส Bytecode คอนสตรัคเตอร์ส่งคืนอ็อบเจ็กต์ Bytecode ซึ่งมีวิธีการดังต่อไปนี้ในการวิเคราะห์ bytecode

Bytecode()

นี่คือตัวสร้าง วิเคราะห์ไบต์โค้ดที่สอดคล้องกับฟังก์ชัน ตัวสร้าง เมธอด สตริงของซอร์สโค้ด หรืออ็อบเจกต์โค้ด นี่คือตัวห่อหุ้มความสะดวกรอบ ๆ ฟังก์ชันมากมาย

>>> string=dis.Bytecode(hello)
>>> for x in string:
      print (x)
Instruction(opname = 'LOAD_GLOBAL', opcode = 116, arg = 0, argval = 'print', argrepr = 'print', offset = 0, starts_line = 2, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello world', argrepr = "'hello world'", offset = 3, starts_line = None, is_jump_target = False)
Instruction(opname = 'CALL_FUNCTION', opcode = 131, arg = 1, argval = 1, argrepr = '1 positional, 0 keyword pair', offset = 6, starts_line = None, is_jump_target = False)
Instruction(opname = 'POP_TOP', opcode = 1, arg = None, argval = None, argrepr = '', offset = 9, starts_line = None, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = None, argrepr = 'None', offset = 10, starts_line = None, is_jump_target = False)
Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 13, starts_line = None, is_jump_target = False)

code_info()

ฟังก์ชันนี้ส่งคืนข้อมูลของอ็อบเจกต์โค้ด Python

>>> dis.code_info(hello)
"Name: hello\nFilename: <pyshell#2>\nArgument count: 0\nKw-only arguments: 0\nNumber of locals: 0\nStack size: 2\nFlags: OPTIMIZED, NEWLOCALS, NOFREE\nConstants:\n 0: None\n 1: 'hello world'\nNames:\n 0: print"

show_code()

ฟังก์ชันนี้จะพิมพ์ข้อมูลโค้ดโดยละเอียดของโมดูล ฟังก์ชัน หรือคลาสของ Python

>>> dis.show_code(hello)
Name: hello
Filename: <pyshell#2>
Argument count: 0
Kw-only arguments: 0
Number of locals: 0
Stack size: 2
Flags: OPTIMIZED, NEWLOCALS, NOFREE
Constants:
   0: None
   1: 'hello world'
Names:
   0: print

ถอดประกอบ()

ฟังก์ชันนี้จะแยกชิ้นส่วนของรหัสวัตถุและให้ผลลัพธ์ที่แบ่งออกเป็นคอลัมน์ต่อไปนี้ -

  • หมายเลขบรรทัดสำหรับคำสั่งแรกของแต่ละบรรทัด

  • คำสั่งปัจจุบัน ระบุว่า -->,

  • คำแนะนำที่มีป้ายกำกับระบุด้วย>>,

  • ที่อยู่ของคำสั่ง

  • ชื่อรหัสปฏิบัติการ

  • พารามิเตอร์การทำงานและ

  • การตีความพารามิเตอร์ในวงเล็บ

>>> codeInString = 'a = 5\nb = 6\nsum = a + b \ nprint("sum = ",sum)'
>>> codeObejct = compile(codeInString, 'sumstring', 'exec')
>>> dis.disassemble(codeObejct)

ผลลัพธ์

1    0 LOAD_CONST 0 (5)
     3 STORE_NAME 0 (a)
2    6 LOAD_CONST 1 (6)
     9 STORE_NAME 1 (b)
3    12 LOAD_NAME 0 (a)
     15 LOAD_NAME 1 (b)
     18 BINARY_ADD
     19 STORE_NAME 2 (sum)
4    22 LOAD_NAME 3 (print)
     25 LOAD_CONST 2 ('sum =')
     28 LOAD_NAME 2 (sum)
     31 CALL_FUNCTION 2 (2 positional, 0 keyword pair)
     34 POP_TOP
     35 LOAD_CONST 3 (None)
     38 RETURN_VALUE

get_instructions()

ฟังก์ชันนี้ส่งคืนตัววนซ้ำเหนือคำแนะนำในฟังก์ชัน วิธีการ สตริงซอร์สโค้ดหรืออ็อบเจกต์โค้ดที่ให้มา ตัววนซ้ำจะสร้างชุดคำสั่งที่ชื่อ tuples โดยให้รายละเอียดของการดำเนินการแต่ละรายการในโค้ดที่ให้มา

>>> it=dis.get_instructions(code)
>>> for i in it:
      print (i)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 0, argval = <code object hello at 0x02A9BA70,
   file "<disassembly>", line 2>, argrepr = '<code object hello at 0x02A9BA70, file "<disassembly>",
   line 2>', offset = 0, starts_line = 2, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 1, argval = 'hello', argrepr = "'hello'", offset = 3, starts_line = None, is_jump_target = False)
Instruction(opname = 'MAKE_FUNCTION', opcode = 132, arg = 0, argval = 0, argrepr = '', offset = 6, starts_line = None, is_jump_target = False)
Instruction(opname = 'STORE_NAME', opcode = 90, arg = 0, argval = 'hello', argrepr = 'hello', offset = 9, starts_line = None, is_jump_target = False)
Instruction(opname = 'LOAD_CONST', opcode = 100, arg = 2, argval = None, argrepr = 'None', offset = 12, starts_line = None, is_jump_target = False)
Instruction(opname = 'RETURN_VALUE', opcode = 83, arg = None, argval = None, argrepr = '', offset = 15, starts_line = None, is_jump_target = False)

ข้อมูลฟังก์ชันอยู่ในรูปของทูเพิลเหมือนอ็อบเจกต์โดยมีพารามิเตอร์ดังแสดงด้านล่าง -

คำแนะนำ
รายละเอียดสำหรับการดำเนินการ bytecode
opcode
รหัสตัวเลขสำหรับการดำเนินการ ซึ่งสอดคล้องกับค่า opcode ที่แสดงด้านล่างและค่า bytecode ในคอลเลกชัน Opcode
opname
ชื่อที่มนุษย์อ่านได้สำหรับการดำเนินการ
arg
อาร์กิวเมนต์ตัวเลขสำหรับการดำเนินการ (ถ้ามี) มิฉะนั้น None
argval
ค่า arg ที่แก้ไขแล้ว (หากทราบ) มิฉะนั้น ให้เหมือนกับ arg
argrepr
คำอธิบายที่มนุษย์อ่านได้ของอาร์กิวเมนต์การดำเนินการ
ออฟเซ็ต
เริ่มต้นดัชนีการทำงานภายในลำดับไบต์โค้ด
starts_line
บรรทัดที่เริ่มต้นโดย opcode นี้ (ถ้ามี) มิฉะนั้น None
is_jump_target
จริงถ้าโค้ดอื่นข้ามมาที่นี่ มิฉะนั้นจะเป็นเท็จ