Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Confused about data alignment for double variables

Tags:

x86

assembly

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)?

like image 921
user8426277 Avatar asked Aug 22 '17 07:08

user8426277


People also ask

Why data alignment is needed?

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.

What does 4 byte aligned mean?

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.

What is meant by aligned address?

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.

What is bit alignment?

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.


1 Answers

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.

like image 179
ネロク・ゴ Avatar answered Oct 29 '22 16:10

ネロク・ゴ