Выравнивание, по модулю; «Следовательно, он может полагаться на ESP = 12 по модулю 16 при каждом входе в функцию». - PullRequest
0 голосов
/ 07 мая 2018

Интересно, кто-нибудь может объяснить использование "по модулю" здесь:

Компилятор Gnu версии 3.x и выше для 32-битных Linux и Mac OS X создает стек указатель выровнен на 16 в каждой инструкции вызова функции. Следовательно, он может полагаться на ESP = 12 по модулю 16 при каждой записи функции. *

Кстати, я знаю, что размер слова здесь составляет четыре байта, и что 12 по модулю 16 равно 12. Кроме того, я действительно не понимаю утверждения, что ESP = 12 по модулю 16.

1 Ответ

0 голосов
/ 07 мая 2018

Значение операции по модулю - это стандартное математическое значение, x mod y - остаток от x div y, где div - целочисленное деление.
Модуль естественно возникает, когда существует периодичность по натуральным числам, чтобы увидеть это, просто возьмите compute x mod 5 для первых 30 чисел.

Выравнивание - это требование, чтобы адрес был кратным некоторому числу n , поскольку x кратен n iif x mod n == 0 , это связывает модуль с выравниванием.

Модуль над натуральными значениями - это одна операция, в которой легко визуализировать фактор-группу : при выравнивании адреса на границе n существует n возможных случаев для рассмотрения, несмотря на возможно бесконечный набор адресов.
Например, для выравнивания и адресации на границе 4 адреса, такие как 1, 5, 9, 13, ..., все эквивалентны, так как они на одно значение больше кратного 4.
Для всех них нам просто нужно добавить 3.

Итак, для выравнивания на границе n мы рассматриваем только случаи, когда адрес равен 0, 1, 2, ... n -1 байт выше кратного n .

Формулировка «ESP = 12 по модулю 16» означает, что esp на 12 байтов выше адреса, кратного 16.
Обратите внимание, что на 12 байтов выше кратного 16 равно 4 байта ниже следующего кратного 16.
Визуализируя 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15, мы можем перейти вправо, добавив 1, а влево вычитая 1.

Причина, по которой esp равен 12 по модулю 16 после вызова, состоит в том, что если при выполнении такой команды, как call function, стек выравнивается на 16 байтов (т. Е. esp равен 0 по модулю 16), то сразу после вызов стека на 4 байта меньше 1 (из-за инструкции call, возвращающей адрес возврата) и, таким образом, 12 байтов из предыдущего кратного 16.

... 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 0 1 2 3 4 5 6 7 8 9 ...
                              ^           ^-- Before the call                    
                              |__ After the call 

1 Помните, что стек увеличивается вниз .

...