MIPS assembly error

Ian Lance Taylor ian@wasabisystems.com
Fri Jul 16 14:09:00 GMT 2004

Jeff Baker <jbaker@qnx.com> writes:

> The following version of the code works perfectly:
> ===================================
> .data
> actives: .byte 0
>           .byte 0
>           .byte 0
>           .byte 0
> ker_stack: .byte 0
>             .byte 0
>             .byte 0
>             .byte 0
> .equ distance,(ker_stack-actives)
> testloc: .word distance
> .text
> li $4,distance
> ===================================
> I'm just unclear as to why one works and one doesn't.

Short answer: no good reason.  The assembler's behaviour is
unpredictable in this regard.

Long answer:

Your first example used .word.  The MIPS assembler automatically
aligns .word values to the natural alignment.  That introduces an
implicit alignment directive, and in the first pass gas is not
immediately sure how much space that will take up.

The new example uses .byte, which does not introduce an alignment
directive.  Even in the first pass gas knows the precise distance
between ker_stack and actives.  So for simplicity gas reduces
(ker_stack-actives) to an absolute value immediately, and the li macro
sees the absolute operand that it requires.

However, using .byte is not 100% reliable, as it is possible, albeit
unlikely, that gas will change frags (an internal data structure which
records the data to put into the output file) at any point during the
sequence of .byte pseudo-ops.  A change in frags will cause gas to not
reduce (ker_stack-actives) to an absolute value during the first pass.


More information about the Binutils mailing list