9

In a bootloader, the second last line is :

TIMES 510-($-$$) db 0

Now, will this command also do the same :

db 510-($-$$) DUP (0)

If not why?

I know what TIMES does, but its not mentioned in my x86 book by Mazidi (Pearson Publication). Any idea why?

And what is the meaning of the $ sign exactly? Different sites have different information about $.

And is the line TIMES 510-($-$$) db 0 absolutely necessary even if my bootloader code is of 512 bytes in size?

So can anyone help me with these questions?

3 Answers 3

5

TIMES and DUP are assembler specific commands, and as such aren't part of x86 assembly language. Same goes for $ and $$.

The $ symbol denotes the current address of the statement, and the $$ denotes the address of the beginning of current section. So the lines with DUP and TIMES calculate the current address in the section and subtracts it from 510. This effectively just zeroes out the section from the current address to the address 510 (not included).

3
  • Okay sir, that helped a lot but will both the statements have the same output. And my book discusses about DUP and it uses MASM. Does Masm also have Times ? Commented Sep 16, 2012 at 8:34
  • 2
    @TotalAnimeImmersion I am not familiar with MASM personally, but I think checking MASM's documentation would be a good start. Commented Sep 16, 2012 at 8:46
  • "This effectively just zeroes out the section from the beginning to the current address." This sentence is wrong! The zeroing happens upwards from the current address. A suggested edit is pending... Commented Nov 2 at 19:58
7

DUP is a specific operand specifier to the DB/DW/etc psuedo-instructions, telling them to repeat a specific value. It can only be used in these data instructions.

TIMES is a generic instruction prefix, telling the assembler to produce multiple copies of the instruction (or psuedo-instruction), whatever it may be.

AFAIK, TIMES is specific to NASM, whereas DUP is widely supported. The reason why TIMES is used in NASM is that one of the primary design goals of NASM was to simplify the use of directives and provide more logical, rational ways of doing things. TIMES can be used in the way you show to fill a space with zeroes, but there are other applications (e.g. aligning loops by generating a sequence of NOP or similar instructions), and this way a single directive can handle multiple jobs. I actually wasn't aware that DUP was supported in NASM at all. I guess DUP was added in a later version for compatibility with MASM-style syntax; I'm not quite sure when; certainly it was quite late, with the result that the documentation doesn't report that it's available), but TIMES is preferred (at least by the original authors of NASM) as being a more generally useful directive.

As to the meaning of $, the reason for different sites having different descriptions is probably again due to the NASM/MASM distinction. In NASM, $ is a variable that contains the address at which the current instruction will be assembled. Note that as it is an address, it may be subject to relocation or otherwise changed during linking. It therefore cannot be used in the TIMES instruction, whose value must be determinable at the point of assembly (it is a critical expression). $$ is the address of the start of the section, so $ - $$ is an offset, which is not subject to relocation and can therefore always be turned into a number. In MASM, $ has the same meaning, but there is no equivalent $$ variable (I believe you would achieve the same things using the WRT operator, but it has been a while since I used MASM so I'm not sure about that).

This should allow you to work out the answer to your third question: TIMES 510-($-$$) db 0 does nothing if $-$$ is equal to 510 because the number of repetitions becomes 0, so if you know that your code is already 512 bytes long you do not need it.

0
2

The difference between TIMES and DUP in assembly language

Both are used for repeating stuff, but the dup operator can only be used in conjunction with data directives like db, dw, and friends (like NASM documentation puts it); whereas times is a prefix that can repeat anything that can legally follow it such as assembly instructions and assembler directives.

The lines TIMES 510-($-$$) db 0 and db 510-($-$$) DUP (0) will produce the very same output, but depending on the exact implementation (and especially judging by an assembler that I wrote), times could be a tiny bit slower as the repeat is on the outside of the db directive whereas dup lives within. (dup can easily translate into a very fast rep stosb).

The questions answered

I know what TIMES does, but it's not mentioned in my x86 book by Mazidi (Pearson Publication). Any idea why?

If that book uses MASM as its assembler then times is not part of the language.

And what is the meaning of the $ sign exactly? Different sites have different information about $.

In many assemblers the $ symbol represents the current offset address within the current code section. Be aware that some assemblers will use a single dot . for this purpose. The address for the current code section in turn is represented by the $$ symbol.

And is the line TIMES 510-($-$$) db 0 absolutely necessary even if my bootloader code is of 512 bytes in size?

If you know for a fact that your bootloader code contains 510 bytes, so leaving 2 bytes for the mandatory signature, then of course it is not required to include this line.
However it is almost always better to leave this line where it is because if you bootloader code exceeds 510 bytes the formula 510-($-$$) will evaluate to a negative number that the times prefix will warn you about. And as we all know: warnings are our friends.

The formula explained

If you develop your bootloader code using an ORG 7C00h directive (which is the preferred way), then both the '$$' and '$' symbols start from 7C00h. As the code generation progresses the '$$' symbol remains fixed, but the '$' symbol gets ever higher values assigned to it. Once enough code was generated and the padding towards the mandatory signature must happen, it is the difference $-$$ that tells us how many bytes we had since code start. Because the signature must reside at offset 510, the subsequent difference 510-($-$$) tells us how many bytes the padding must be. The times 510-($-$$) db 0 line then does the actual padding.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.