Computed lengths are used as 32 bit values, even when they are less
than 128. Symbols assigned values less than 128 and used generate
a one byte immediate in pushl $value, while symbols with computed
lengths appear as 4 byte immediate values, even though they have the
same small value.
azp:68% cat b.s ; as -a b.s -o b.o
msg: .asciz "hello world.\n"
msglen = .-msg-1 # determine length, an absolute value
#msglen=msglen & 0xff # this crashes the assembler if included
foo = 13
pushl $13 # this generates a 2 byte instruction
pushl $msglen # this generates 4 bytes for the same
pushl $foo # but this generates 2 bytes
GAS LISTING b.s page 1
3 0000 68656C6C msg: .asciz "hello world.\n"
4 msglen = .-msg-1 # determine length, an
5 #msglen=msglen & 0xff # this crashes the
assembler if included
6 foo = 13
8 000e 6A0D pushl $13 # this generates a 2
9 0010 680D0000 pushl $msglen # this generates 4 bytes
for the same
10 0015 6A0D pushl $foo # but this generates 2 bytes
11 0017 FF350000 pushl msg
GAS LISTING b.s page 2
b.s:3 .text:00000000 msg
NO UNDEFINED SYMBOLS
This is a result of delayed expression evaluation. If you assemble without
listings turned on, the optimal push insn will be chosen.
Some background info I should have added to help people looking through the bug
<bje> alanm: Any opinions on PR 998?
<bje> I gather from your comments that you've stated, "That's the way it is".
Is there anything more to do here?
<alanm> bje, depends on how much work you want to do. the problem is that with
listings turned on, each line is in a separate frag. you generally can't
subtract labels in different frags (one of the frags might be something like
.align) until final placement, so we punt when evaluating the size expression.
you could a) rewrite gas listing code from scratch to not use frags, b) look
back thru some frags when evaluating expressions
<bje> It seems like a pretty obscure corner case.
<alanm> yes, but people do keep running into the problem, even with listings
disabled. eg. you might need a new frag simply because memory allocated for old
one runs out. in that case the two frags have a fixed relationship wrt start
address, so you could subtract a label in one frag from a label in the other.
not doing so breaks anything that depends on being able to evaluate such an
expression early. conditional assembly, .org/.space, relax...