This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

GNU assembler, linker and align



I was looking at my code when I noticed something very odd. The code is in two files and assembled using msp430-elf-as and each has .text sections. What I noticed is that there was a gap between the last code in one file and the first code in the second with the second starting at 0x4c00.


Things got even stranger when I looked at the data segment. The linker had placed it at 0x4400 (the start of FRAM) and while it is short, it occupies a full 1K with code starting at 0x4800.


The problem appears to be caused by a .align 10 pseudo op at the end of the second code file. I use this because I am using the MPU and the code needs to know where the start of memory that it can write to is at.

But why is an align directive at the end of one file changing the alignment for everything?

I cut it down to a very simplified test case to show that it was in fact this .align 10 directive.

  • For the alignment at the end of the section to work, the beginning of the section must also be aligned to that value.
  • Except that the.align pseudo op is only advertised as advancing the current location so that it is aligned. It doesn't say that it will align separate chunks of the text segment. Or that it will align the end of a non-existent data segment.


    That last part isn't quite accurate. I have discovered that the linker script is allocating 6 bytes of storage in .rodata and .upper.data so that even if I don't allocate anything there, it still exists and this bug makes that 6 bytes occupy 1K. This short program links to occupy 2K:

    	
    	.text
    sys_init:	
    	br	#sys_init
    	.align	10
    ctop:	
    	.end
    	
    

  • Aligning the section is necessary.

    Regardless of what the documentation says, when you have a section starting at address 0x4404, aligning to 16 bytes just would not work.

  • I guess that with all of the other things that the linker does I thought that it would handle this as well. Who knew that in this case it would get stupid.

    But I would still like to know why the linker scripts are allocating storage. Every single script includes "LONG(0); /* Sentinel. */" in .rodata and a few include "SHORT(1);" in .upper.data.

**Attention** This is a public forum