Ближайшая сборка, связанная с байт-кодом Python - PullRequest
0 голосов
/ 15 октября 2019

У меня есть следующая базовая функция Python:

def squared(num):
    if num < 2:
        print ('OK!')
    return num * num

, которая производит следующий байт-код:

>>> dis.dis(squared)
  2           0 LOAD_FAST                0 (num)
              3 LOAD_CONST               1 (2)
              6 COMPARE_OP               0 (<)
              9 POP_JUMP_IF_FALSE       20

  3          12 LOAD_CONST               2 ('OK!')
             15 PRINT_ITEM          
             16 PRINT_NEWLINE       
             17 JUMP_FORWARD             0 (to 20)

  4     >>   20 LOAD_FAST                0 (num)
             23 LOAD_FAST                0 (num)
             26 BINARY_MULTIPLY     
             27 RETURN_VALUE        

Большинство из вышеперечисленных выглядят как mov и jmp -типаоператоры. Тем не менее, что следующие слова наиболее близко означают в сборке?

LOAD_FAST, LOAD_CONST?

Что может быть ближайшими инструкциями по сборке для этого?

1 Ответ

3 голосов
/ 15 октября 2019

Байт-код Python предназначен для стековой виртуальной машины, чтобы упростить интерпретаторы и тратить меньше места на адреса (например, номера регистров), делая их неявными. Загрузки загружаются в этот стек.

Если вы транслитерируете это в очень буквальной и умственной форме в asm-эквивалент для целых чисел фиксированной ширины (в отличие от целых чисел произвольной точности Python), каждый LOAD_FAST может быть загрузкой из локальногопеременная (в памяти в стеке) в регистр. Но вам все равно придется выбирать, какие регистры, а реальные ISA имеют ограниченное количество регистров. Но да, LOAD_FAST похож на загрузку.

Конечно, если бы вы не были преднамеренно буквальными только ради этого, вы бы знали, что у вас уже есть num в регистре и не загружаете его снова,Таким образом, вы будете использовать инструкцию, которая читает один и тот же регистр дважды, например, imul eax, eax

И у вас будут локальные переменные, живущие в регистрах, когда это возможно, не выливая их в стек в первую очередь, пока вы не запуститеиз регистров.


Если вы хотите узнать об asm для процессоров, вы можете написать эквивалентную функцию на C и скомпилировать ее (с включенной оптимизацией, по крайней мере -Og, если не -O2 или-O3) в проводнике компилятора Godbolt: https://godbolt.org/. Или на вашем рабочем столе, но Мэтт Годболт написал хорошую фильтрацию, чтобы удалить шум и оставить только интересные части. См. Также Как удалить "шум" из вывода сборки GCC / clang?

...