Значение операции по модулю - это стандартное математическое значение, 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 Помните, что стек увеличивается вниз .