5

What does the directive .align n do in an array?
To be more specific let's say that I have the following part of code:

array: .align 2
       .space 800     

What's its importance and why not just skip it and use

       .space 800

This is a school's assignment theory question.

Cœur
  • 37,241
  • 25
  • 195
  • 267
  • There is a *very similar question* to yours: [Align instruction on MIPS](https://stackoverflow.com/questions/1021068/align-instruction-on-mips). I was tempted to close yours as a duplicate but I'm not sure: you gave a little bit more context, that maybe requires specific handling. – Margaret Bloom Dec 28 '16 at 10:20
  • It's very rare that you want the label to come before the `.align` directive. That means the label address is still possibly-unaligned. – Peter Cordes Jan 22 '18 at 07:15
  • Oops, nvm, apparently MARS labels work differently from every other assembler I've ever seen, and `.align` *after* a label can change the label's address. – Peter Cordes Jan 22 '18 at 11:08
  • @petercordes The way that is written ensures that the alignment for an integer "array" will be properly done when strings are defined before it. Be advised the time that this was written I was using PCspim – Konstantinos T. Pantelis Mar 02 '19 at 16:55
  • The correct way to use `.align` in normal GAS is `.align n` ; `array: .space 800`. That way the padding inserted by `.align` is *before* the label, making the label aligned. It's weird voodoo magic for `.align` *after* a label to instead place the padding before the label. – Peter Cordes Mar 02 '19 at 18:11
  • See also [MARS MIPS simulator's built-in assembler aligns more than requested?](https://stackoverflow.com/q/59926448) for more details about exactly how it works. Note that `.word` has implicit alignment to a word boundary (unless you disable it with `.align 0`), but `.space` doesn't. – Peter Cordes Mar 21 '20 at 03:01
  • Related: [Error #5: Unaligned word memory reference](https://stackoverflow.com/q/47482102) is a decent canonical duplicate for questions with misaligned loads or stores to static storage. – Peter Cordes Oct 09 '20 at 06:17

1 Answers1

7

Taken directly from MARS helping tooltips:

Align next data item on specified byte boundary (0=byte, 1=halfword, 2=word, 3=double)

Consider this code

  la $t0, array

.data
  .space 3

array: 
  .space 12

This is assembled into

lui $at, 0x1001
ori $t0, $at, 0x0003          #$t0 = 0x10010003

showing that array is at address 0x10010003.


Using an .align directive:

  la $t0, array

.data
  .space 3

array:
  .align 3 
  .space 12

Gives:

lui $at, 0x1001
ori $t0, $at, 0x0008          #$t0 = 0x10010008

Now the address is 0x10010008.


The difference is that the latter address is aligned on double boundary.
A double is 8 bytes long and the address is a multiple of 8 bytes.

Alignment gives better performance because the CPU reads memory in chunks of words and this blocks starts at address multiple of four (0x0, 0x4, 0x8, ...).
If a word at 0x3 is requested, the CPU need to read the one at 0x0 and the one at 0x4 and merge the results.

Unaligned accesses are explicitly not supported in some architecture. If I recall correctly, MIPS is not such strict when it comes to data (but it is for code).

Pitfall

Beware that .align n align the next data item on 2n boundary, or equivalently (left as an exercise to the reader) it moves the data item to an address whose lower n bits are zero.

MARS appears, contrary to most assembler, to "attach" labels to the next space allocating directive (e.g. .byte, .space, etc.) and not the current location counter.
Thus the label can be moved between the .align and .space directives.

  .align 2            |    array: 
array:                |      .align 2
  .space 12           |      .space 12 
Margaret Bloom
  • 41,768
  • 5
  • 78
  • 124
  • How can `.align` not take space? It isn't equivalent to emitting padding bytes? A `.align` directive *after* a label can change the address of the label? So it would affect a size calculation if you wrote `msg: blah blah` / `endmsg:` / ... / `.align 2` / ... / something with `endmsg - msg`. This all seems unlikely unless MARS's assembler is vastly different from GAS. If I'm correct, you should address this mistake in the question first, then your example with `.align` changing the address of `array:` will be correct. – Peter Cordes Jan 22 '18 at 07:19
  • @PeterCordes What I was trying to say is this: The `.align` directive changes the alignment of the next directive that allocates space (e.g. `.byte` and similar). If no such directive is present the directive is ignored! Regarding "taking no space": it's badly worded. MARS seems to attach labels to the next space allocating directive, thus the two example above are equivalent because the label points to `.space`'s starting address. I'll reword it, thank you very much. – Margaret Bloom Jan 22 '18 at 09:34
  • Wow, that is *super*-weird. So you can't safely put labels on the end of things! It's a surprising claim, but if you checked it out then that's sufficient evidence that it really does work this way in MARS. – Peter Cordes Jan 22 '18 at 11:07
  • 1
    @PeterCordes Actually, MARS seems to take the most restricting Align directive (correctly, If I say so) but still labels don't point to the current location counter. This may even be a bug. The code `.align 2 / test: / .align 3` aligns `test` on 2^3 while `.align 2 / test:` aligns it on 2^2. Putting a `.byte 0` after the label keeps it aligned on 2^2. It's a confusing implementation. Yet, MARS is just simulator for learning MIPS. – Margaret Bloom Jan 22 '18 at 11:48
  • 1
    Probably a good idea to recommend always putting `.align` *before* labels, as a good habit that also works with other assemblers. Unless there's some reason to avoid that with MARS/SPIM. So IMO change the first example in your "using .align" section. – Peter Cordes Mar 02 '19 at 18:15
  • 1
    See also [MARS MIPS simulator's built-in assembler aligns more than requested?](https://stackoverflow.com/q/59926448) - after digging into this deeper, it seems MARS implement classic MIPS assembly like SGI documents, where this magic effect on earlier labels was a thing. Also that `.word` has implicit alignment (unless you disable it with `.align 0`) but `.space` doesn't. – Peter Cordes Mar 21 '20 at 03:06