2

I'm using gnu assembler on a TI MCU (msp430) and want to define variables of mixed alignments in assembly; some are byte aligned, others must be word (16bit) aligned. I am also needing to keep some variables private to an assembly language module, and others common (global). So, I'd like to us .lcomm -- as the default, and then use .global to over-ride it when appropriate.

But even after applying the byte align directive, I am getting alignment errors during linking of a GCC compiled program:

ssegLED.c:200: dangerous relocation: unaligned address

And that line is merely trying to access data that is supposed to be word aligned:

if (knob) { ... }

In the assembly language module causing the problem, I'm trying to make the data pack efficiently into memory; So I want to use subsections to group like kinds of data together so that holes don't form between differently aligned data. eg: all word aligned data I'd like in the default subsection (0) but unaligned data, I want in subsection 1.

Here's the assembly / .s code used to define four variables: keystroke, quadrature, keystate, and knob. The first three are byte aligned, the last is word aligned.

.section    .bss    ;; doesn't matter if .bss or .section .bss -- same err.
.subsection 1
.balign     1 ;; can add a  ,0 -- but it changes nothing

.global     keystroke
.type       keystroke,@object
.size       keystroke,1 ;; Tried with and without this line, no change...
.lcomm      keystroke,1

.lcomm      quadrature,1
.lcomm      keystate,1  

.section    .bss
.subsection 0
.balign     2 ;; tried adding ,0 -- but it fixes nothing

.global     knob  ;; Present knob value
.type       knob, @object
.size       knob, 2     ;; doesn't affect error whether commented out/not
.lcomm      knob, 2

Now, there are two things I am doing which ought to prevent mis-alignement issues; According to the GNU AS manual, subsection 0 should be placed in memory before subsection 1; therefore section 0 automatically starts out word aligned as the default section; and secondly, I'm using the .balign directive explicitly.

But it doesn't work... and changing to .b2align doesn't fix it, etc.

I can make the error go away by explicitly adding another byte aligned variable to the the subsection 1 variables keystroke, quadrature, and keystate; so that the whole subsection ends on a word boundary; but as the offending subsection has a lower number (0), the alignment of subsection (1) ought not have any effect....

Secondly, if I change all the .lcomm into .comm the error also goes away; but I have no idea why.

What's going on? and what am I doing wrong?

1 Answers1

0

.lcomm puts your symbol into the .bss section (subsection 0) implicitly, no matter what the current section or subsection is. As such your symbols are simply in the order they appear in the source, that is why knob comes after the single-byte variables. It's also why .balign makes no difference, since that applies to the current (sub)section.

Try using .fill instead. According to my tests that seems to work.

Jester
  • 56,577
  • 4
  • 81
  • 125
  • Yes indeed.... undocumented behavior. It's weird that fill would even work on a section which rejects data. But, it does seem to work -- so overall, this looks like a bug in "as" design or documentation. I'm not sure how to report it -- but I think I'll just make a macro for now to use .fill, which can be easily changed if the problem is ever fixed. Thanks. :) – Andrew of Scappoose Mar 13 '13 at 00:36
  • Everything is documented that I said. You can use the `.skip` directive if you think that's more readable. I don't see any problem in GAS apart from having multiple directives doing the same thing. Maybe I didn't explain the situation clearly enough. – Jester Mar 13 '13 at 02:01