I have read that a double
variable (8 bytes) must be 8 bytes aligned.
Now if I am writing the entire code for my program, then I can make the double
variables 8 bytes aligned without any problem.
But say that I have the following scenario: I create a function that creates a double
variable on the stack, and I give this function to someone else to use it in his program. Now when my function is called, my function will have no idea if the double
variable will be created on an address that is dividable by 8!
Can this problem be solved (note that I do not care about the negligible performance loss from not aligning my double
variables, but I am just interested in knowing if there is a solution to this problem)?
Alignment helps the CPU fetch data from memory in an efficient manner: less cache miss/flush, less bus transactions etc. Some memory types (e.g. RDRAM, DRAM etc.) need to be accessed in a structured manner (aligned "words" and in "burst transactions" i.e. many words at one time) in order to yield efficient results.
For instance, in a 32-bit architecture, the data may be aligned if the data is stored in four consecutive bytes and the first byte lies on a 4-byte boundary. Data alignment is the aligning of elements according to their natural alignment.
The alignment of the access refers to the address being a multiple of the transfer size. For example, an aligned 32 bit access will have the bottom 4 bits of the address as 0x0, 0x4, 0x8 and 0xC assuming the memory is byte addressed. An unaligned address is then an address that isn't a multiple of the transfer size.
Alignment refers to the arrangement of data in memory, and specifically deals with the issue of accessing data as proper units of information from main memory. First we must conceptualize main memory as a contiguous block of consecutive memory locations. Each location contains a fixed number of bits.
Inside of a function you can force the stack to be 8-byte aligned by setting to zero the three least significant bits of esp
. This can be achieved by means of the and
instruction:
andl $0xfffffff8, %esp
The resulting esp
will be equal (i.e.: esp
was already aligned) or lower than the previous one. Since the stack on the x86 architecture grows downwards, this results in a padding with a size between 0-7 bytes allocated on the stack.
Note that if esp
was already 8-byte aligned before executing the and
instruction (i.e.: its three least significant bits were already zero), no padding at all (i.e.: a padding of 0 bytes) is created on the stack.
When leaving the function, the previous saved value of esp
will be restored if you are using the common function prologue and epilogue:
myFunction:
//prologue: save the current stack frame
pushl %ebp
movl %esp, %ebp
andl $0xfffffff8, %esp
//stack now 8-byte aligned
//...
leave //restore the previous stack frame
ret
This way the previously allocated padding will be now deallocated from the stack.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With