Computer >> 컴퓨터 >  >> 프로그램 작성 >> Python

Python 바이트코드용 디스어셈블러

<시간/>

파이썬 표준 라이브러리의 dis 모듈은 파이썬 바이트코드를 사람이 읽을 수 있는 형태로 분해하여 분석에 유용한 다양한 기능을 제공합니다. 이것은 최적화를 수행하는 데 도움이 됩니다. 바이트코드는 인터프리터의 버전별 구현 세부정보입니다.

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는 바이트코드 클래스에 정의되어 있습니다. 생성자는 바이트코드를 분석하기 위해 다음과 같은 메서드를 가진 바이트코드 개체를 반환합니다.

바이트코드()

이것은 생성자입니다. 함수, 생성기, 메서드, 소스 코드 문자열 또는 코드 개체에 해당하는 바이트 코드를 분석합니다. 이것은 많은 기능을 둘러싼 편리한 래퍼입니다.

>>> 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)

코드 정보()

이 함수는 파이썬 코드 객체의 정보를 반환합니다.

>>> 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()

이 함수는 제공된 함수, 메서드, 소스 코드 문자열 또는 코드 개체의 지침에 대한 반복자를 반환합니다. 반복자는 제공된 코드의 각 작업에 대한 세부 정보를 제공하는 튜플이라는 일련의 명령어를 생성합니다.

>>> 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)

함수 정보는 아래와 같이 매개변수가 있는 객체와 같은 튜플 형식입니다 -

지시
바이트 코드 작업에 대한 세부 정보
opcode
아래에 나열된 opcode 값과 Opcode 컬렉션의 바이트코드 값에 해당하는 작업에 대한 숫자 코드입니다.
작업명
사람이 읽을 수 있는 작업 이름
인수
작업에 대한 숫자 인수(있는 경우), 그렇지 않으면 없음
argval
해결된 arg 값(알고 있는 경우), 그렇지 않으면 arg와 동일
argrepr
사람이 읽을 수 있는 작업 인수 설명
오프셋
바이트 코드 시퀀스 내 작업 시작 인덱스
starts_line
이 opcode에 의해 시작되는 라인(있는 경우), 그렇지 않으면 없음
is_jump_target
다른 코드가 여기로 점프하면 True, 그렇지 않으면 False