对齐,取模; "Consequently it can rely on ESP = 12 modulo 16 at every function entry."

Alignment, modulo; "Consequently it can rely on ESP = 12 modulo 16 at every function entry."

不知道有没有人能在这里解释一下"modulo"的用法:

The Gnu compiler version 3.x and later for 32-bit Linux and Mac OS X makes the stack pointer aligned by 16 at every function call instruction. Consequently it can rely on ESP = 12 modulo 16 at every function entry. *

顺便说一句,我知道这里的字长是四个字节,12模16就是12。除此之外我真的不明白ESP = 12模16的说法。

modulo operation的含义是标准的数学含义,x mod yx div y的其余部分,其中div是整数除法。
当自然数具有周期性时自然会出现模数,要看到这一点,只需对前 30 个数字进行计算 x mod 5

对齐要求地址是某个数字n的倍数,因为xn的倍数 iif x mod n == 0,这将 modulus 与对齐链接起来。

自然数上的 modulus 是一种很容易可视化 quotient group 的操作:当在 n 边界对齐地址时,尽管地址集可能是无限的,但仍有 n 种可能的情况需要考虑。
例如,要在 4 边界对齐和寻址,地址 1、5、9、13 等都是等价的,因为它们是 4 的倍数以上的一个值。
对于所有这些,我们只需要添加 3。

因此,对于 n-边界处的对齐,我们只考虑地址为 0、1、2、... n[ 的情况=55=]-1 字节以上 n 的倍数。

措辞"ESP = 12 modulo 16"表示esp比16的地址倍数高12个字节。
请注意,比 16 的倍数高 12 个字节等于比下一个 16 的倍数低 4 个字节。
可视化 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 我们可以向右加 1,向左减 1。

调用后esp是12modulo 16的原因是,当执行call function这样的指令时,堆栈按16字节对齐(即esp 是 0 modulo 16) 然后在调用之后堆栈立即低 4 个字节1(由于 call 指令将 return address),因此从前一个 16 的倍数中减去 12 个字节。

... 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 请记住,堆栈增长 向下