Почему возникают побочные потоки и что они достигают?

Что такое байтовый разлив?

Когда я удаляю ASM x86 из промежуточного представления LLVM, сгенерированного из программы C, существует множество разливов, обычно размером 4 байта. Я не могу понять, почему они происходят и что они достигают.

Они, кажется, "вырезают" кусочки стека, но необычным образом:

## this fragment comes from a C program right before a malloc() call to a struct.
## there are other spills in different circumstances in this same program, so it
## is not related exclusively to malloc()
...
sub ESP, 84
mov EAX, 60
mov DWORD PTR [ESP + 80], 0
mov DWORD PTR [ESP], 60
mov DWORD PTR [ESP + 60], EAX # 4-byte Spill
call malloc
mov ECX, 60
...

Ответ 1

Разлив реестра - это просто то, что происходит, когда у вас больше локальных переменных, чем регистров (это аналогия - действительно, смысл в том, что они должны быть сохранены в памяти). Инструкция сохраняет значение EAX, вероятно, потому что EAX сбивается malloc, и у вас нет другого запасного регистра для его сохранения (и по какой-то причине компилятор решил, что ему потребуется константа 60 в регистре позже).

По внешнему виду, компилятор, возможно, пропустил mov DWORD PTR [ESP + 60], EAX и вместо этого повторил mov EAX, 60, где он иначе mov EAX, DWORD PTR [ESP + 60] или любое другое его значение, поскольку сохраненное значение EAX не может быть иным, чем 60 в это пункт. Однако компиляция не гарантируется как оптимальная.

Помните, что после sub ESP, 84 размер стека не регулируется (за исключением команды вызова, которая, разумеется, выталкивает адрес возврата). Следующие инструкции используют ESP как смещение памяти, а не пункт назначения.