Esto no suena a apilar específico, pero la alineación en general. Quizás piense en el término entero múltiple.
Si tiene elementos en la memoria que son un byte de tamaño, unidades de 1, entonces digamos que todos ellos están alineados. Las cosas que tienen dos bytes de tamaño, luego los enteros multiplicados por 2 se alinearán, 0, 2, 4, 6, 8, etc. Y los múltiplos no enteros, 1, 3, 5, 7 no se alinearán. Los elementos que tienen 4 bytes de tamaño, los múltiplos enteros 0, 4, 8, 12, etc. están alineados, 1,2,3,5,6,7, etc. no lo están. Lo mismo vale para 8, 0,8,16,24 y 16 16,32,48,64, y así sucesivamente.
Lo que esto significa es que usted puede mirar en la dirección base para el artículo y determinar si está alineado.
size in bytes, address in the form of
1, xxxxxxx
2, xxxxxx0
4, xxxxx00
8, xxxx000
16,xxx0000
32,xx00000
64,x000000
and so on
En el caso de una mezcla en datos con instrucciones en el segmento .text es bastante sencillo para alinear datos según sea necesario compilador (bueno, depende de la arquitectura). Pero la pila es una cosa de tiempo de ejecución, el compilador normalmente no puede determinar dónde estará la pila en tiempo de ejecución. Entonces, en el tiempo de ejecución, si tiene variables locales que necesitan alinearse, necesitará que el código ajuste la pila de forma programática.
Digamos por ejemplo que tiene dos elementos 8 bytes en la pila 16, el total de bytes, y que realmente quiere que alineados (en 8 límites de bytes). Al ingresar, la función restaría 16 del puntero de la pila como de costumbre para dejar espacio para estos dos elementos. Pero para alinearlos, debería haber más código. Si queríamos estos dos elementos de 8 bytes alineados en los límites de 8 bytes y el puntero de la pila después de restar 16 era 0xFF82, los 3 bits inferiores no son 0, por lo que no están alineados. Los tres bits más bajos son 0b010. En un sentido genérico, queremos restar 2 del 0xFF82 para obtener 0xFF80. La forma en que determinamos que es un 2 sería haciendo anding con 0b111 (0x7) y restando esa cantidad. Eso significa operaciones alu y un restar. Pero podemos tomar un atajo si nosotros y con el valor de complemento de 0x7 (~ 0x7 = 0xFFFF ... FFF8) obtenemos 0xFF80 usando una operación alu (siempre que el compilador y el procesador tengan una sola forma de código de operación para hacer eso, si no puede costarle más que el yy restar).
Esto parece ser lo que su programa estaba haciendo. Anding con -16 es lo mismo que anding con 0xFFFF .... FFF0, lo que resulta en una dirección alineada en un límite de 16 bytes.
Así que para terminar con esto, si usted tiene algo así como un puntero de pila típica, que se cuela por la memoria de las direcciones más altas para disminuir las direcciones, a continuación, desea
sp = sp & (~(n-1))
donde n es el número de bytes alinear (debe haber poderes, pero está bien que la alineación por lo general involucre poderes de dos). Si usted tiene opinión realizado un malloc (direcciones aumentan de bajo a alto) y quieren alinear la dirección de algo (recuerde malloc más de lo necesario por lo menos el tamaño de alineación) y luego
if(ptr&(~(n-)) { ptr = (ptr+n)&(~(n-1)); }
O si lo desea simplemente tome el si está allí y realice el agregado y la máscara cada vez.
muchas/la mayoría de arquitecturas que no son x86 tienen reglas y requisitos de alineación. x86 es demasiado flexible en lo que respecta al conjunto de instrucciones, pero en lo que respecta a la ejecución, puede/pagará una penalización por accesos no alineados en un x86, por lo que aunque pueda hacerlo, debe esforzarse por mantenerse alineado como lo haría con cualquier otra arquitectura. Tal vez eso es lo que estaba haciendo este código.
http://en.wikipedia.org/wiki/Data_structure_alignment – chrisaycock
No tiene mucho sentido mirar código de máquina sin habilitar el optimizador. –