Aligning a buffer in assembly

Go To Last Post
10 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Hi,

Is there a way, in GNU as, to allocate space for a buffer in .bss that is aligned to a 256-byte boundary?

I have tried using the .align directive, but for some reason ld throws the error 'avr-ld: region bss is full (test.elf section .bss)'.

This is how I am allocating space for the buffer:

.section .bss
.align 256
.comm audio_buffer, 0x100

This is my linker script for the target device which is an ATmega168 (note that this project is 100% assembly, no C):

OUTPUT_FORMAT("elf32-avr","elf32-avr","elf32-avr")
OUTPUT_ARCH(avr:5)

MEMORY
{
	text        (rx): ORIGIN = 0, LENGTH = 0x4000
	bss         (!rx): ORIGIN = 0x800100, LENGTH = 0x400
}


__stack = 0x800100 + 0x400 - 2;


SECTIONS
{
	.text :
	{
		*(.vectors)
		*(.init0)
		*(.audio_init)
		*(.main)
		*(.text)

	} > text
	
	.bss :
	{
		*(.bss)

	} > bss
}
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

If it's asm why use ".bss" which is a memory section in support of C? Just create a new .my_vars or something and then place it with a --section-start in the LDFLAGS. I wouldn't have thought you'd need to mess with the linker scripts.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
If it's asm why use ".bss" which is a memory section in support of C?
For the simple reason that avr-size displays the usage of the .bss section and I can't figure out how to make it show the usage for custom sections. Also, the .comm and .lcomm directives place variables in the .bss section (I believe that this is hard coded behavior).
Quote:
I wouldn't have thought you'd need to mess with the linker scripts.
I wouldn't if this were a C project, there would be no need. In this project however I have specific requirements for the order in which things are linked (hence the various sub-sections under .text). The default linker script also includes all sorts of guff for linking in crt initialization etc. which I don't want to have to worry about.

I did originally define a custom section with specified start address and yes that works fine. I was wondering however if there is a more 'proper way' of achieving the alignment. I'd quite like to know why the .align directive is causing the error I described above.

EDIT:I've just discovered that 'avr-size -A' displays usage for ALL sections in sysv format.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:

default linker script also includes all sorts of guff for linking in crt initialization etc. which I don't want to have to worry about.

Not if you use -nodefaultlibs and/or -nostartfiles

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Quote:
Not if you use -nodefaultlibs and/or -nostartfiles
Okay, I'll bear that in mind for the future. Doesn't get around my link order requirements though (which I usually have for asm projects).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I've gone back to using a custom section now, only instead of specifying where to put the section explicitly, I've now modified my linker script as follows:

	.bss :
	{
		*(.bss)
		. = ALIGN(0x100);
		*(.audio_buffer)

	} > bss

I'd still rather perform the alignment in the assembly rather than via the linker script (or a command-line argument) though. Any thoughts? I suppose the downside of performing the alignment using the assembler could be that a whole load of RAM could be wasted with padding, depending on the order in which variables are linked if the linker is left to its own devices. Maybe I should quit whilst I'm ahead?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I think I would skip .align, as it may be trying to align in 'bit positions' instead of bytes, or words or ?. The .comm thing may also be causing problems (you are aligning .bss, but .comm may not be playing along with the .bss alignment even though its in the same section). Or something.

.balign is supposed to always align in bytes (power of 2 only), so that could help.

Or use the alignment feature of .comm-
.comm audio_buffer 0x100, 256

But as long as you are creating a linker script, may as well put it in there. If you put the .audio_buffer section first, you don't even need alignment, and will not be wasting sram.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can, of course, use .org in .section data or bss but the problem with it is that it's just a relative increment, not an absolute positioning as that's done by the linker/linker script. But if you had nothing else in .data and you know that it's based at 0x60 or 0x100 on a particular AVR you may be able to use this.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks for your suggestions. I have decided to stick with using the linker script to specify the alignment. For this application I will probably go with curtvm's suggestion and ensure the audio_buffer is linked first so it is positioned at 0x800100. I'll use the . = ALIGN () expression in the linker script for any further alignment critical variables that cannot be solved purely via linking order and size.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

In gas, use either

.balign 256

or

.p2align 8

The gnuisance assembler does prove a .align directive, but its meaning varies between processors -- sometimes it's the same as .balign, sometimes (presumably including the AVR) it's the same as .p2align -- so trying to use it will drive you insane.