I found a good post:
(The answer is very professional)
Hey all.
I'm a complete beginner in assembly and have chosen NASM to work my way up. but I have a problem with the pseudo-instruction set. more precisely, I don't understand how the expressions "$ and $" are used in correlation with times.
It's no problem for me to understand what "times" does, but I do not understand the expressions used together with times.
Like;
Times 512-($-$) db 0
It is explained what it does (in the tutorial), but not how it is done.
My questions according to this example;
1. Why is there a dash ("-") after 512 and before "("?
2. Can someone elaborate what $ means and is used?
3. Can someone elaborate waht $ means and is used?
I read the 2 lines of description about $ and $ multiple times now, and I still don't understand what they are. Can someone help?
The answer is as follows:
The mysterious '-' is a minus sign. That takes care of that part.
Nasm uses '$' for several purposes, in this case it's "here"-the current assembly location. Actually, the location at the beginning of the line.
'$' Is the beginning of the current section.
You might reasonably think that '$' wocould be enough, but '$', like any symbol, is a "relocatable value ". that is, the linker and loader can alter this value in ways Nasm knows nothing about. in the specific case of "-f bin" output, Nasm acts as its own linker,
But that happens in the "output driver", and we need to know this value in the actual "assemble" routine, which runs first. this is what Nasm means when it says "not a scalar value ". it's a vector ??? No, it's a "relocatable value ".
In some cases, a relocatable value is okay...
Code: [Select]
mov eax, $
Nasm doesn't need to know the value at "assemble-time", it codes "mov eax, (this label)", and the linker/loader will fill in the relocated value. but:
Code: [Select]
mov eax, $ << 1
... Now we're re asking Nasm to do an assemble-time calculation on a value it doesn't know, so it whines.
The difference between two labels (in the same section !) Is a "scalar value ". the linker/loader can change the two values, but the distance between them remains the same. therefore, we can do a calculation on it-and it's an acceptable argument to "times ".
Code: [Select]
org 0 ; the default, if no origin specifiedsection .text ; the default, if no section specifiednopnopnop ; three bytes of "code"times 512 - ($ - $$) db 0
In this case, '$' is 3 and '$' is 0, so we're emitting 509 zeros to bring the total file size to 512 bytes. in this case, just '$' wocould have worked, if Nasm wocould accept it, which it won't.
Code: [Select]
org 7C00hsection .textnopnopnop ; three bytes of "code"times 512 - ($ - $$) db 0
Now, '$' is 7C03h and '$' is 7C00h. we're re still adding 509 zeros to pad to 512 bytes, but in this case '$' by itself wocould ** not * do what you want!
The expression "512-($-$)" can be written without the parentheses as "512 + $-$", but this is even less clear (IMHO ). in a bootsector, 510 is more common than 512, since we want the two byte "boot signature" after it, and the entire bootsector needs
To be 512 bytes, but that doesn't alter '$' and '$ '...
Does that make you less confused, or more?
Best,
Frank