Alexander Bolinsky Alexander Bolinsky - 1 year ago 44
Linux Question

How is the $ token treated when used under a label vs in a single line?

The NASM manual includes the following on the $ token in section 3.5:

$ evaluates to the assembly position at the beginning of the line containing the expression

and earlier in section 3.1 there is a note about source lines:

NASM uses backslash (\) as the line continuation character; if a line ends with backslash, the next line is considered to be a part of the backslash-ended line.

I have written the following assembly which allocates data as I want it to (a 20-byte array that contains a string, followed by underscores until the second-to-last index of the array, followed by a newline character):

section .data
buf: ; define 20-byte buffer
db 'Hello, world!' ; declare string constant
times 19-$+buf db '_' ; declare byte with value '_' after string and up to index 19 in buffer
db 0xa ; declare byte with newline character 0xa (10) at end of buffer
len equ $-buf ; define len to be size of buf

It works, but I am a little confused about why $+buf is used instead of $-buf on the fourth line. My understanding is that each line is a source line, $ refers to the beginning of the line, and buf refers to the beginning of the data labeled "buf".

If I use $-buf in place of $+buf, NASM spits out:

error: non-constant argument supplied to TIMES

What is going on here?

Answer Source

You're missing the fact that there's a - ahead of the $ in the original.

19-$+buf = buf-$ + 19

It's still an address difference, not sum.

buf refers to the beginning of the data labelled "buf"

Yes, but your terminology is sloppy. buf is the address of the position where you put the buf label. It's just a position which you can use to access bytes at known offsets from it. There's no clear way to tell which bytes "are labelled buf". In this case, probably the whole 20-byte buffer (including the newline after the line that pads with _) is accessed through buf.