The Netwide Assembler: NASM

Next Chapter | Previous Chapter | Contents | Index

Chapter 10: Troubleshooting

This chapter describes some of the common problems that users have been known to encounter with NASM, and answers them. It also gives instructions for reporting bugs in NASM if you find a difficulty that isn't listed here.

10.1 Common Problems

10.1.1 NASM Generates Inefficient Code

I get a lot of `bug' reports about NASM generating inefficient, or even `wrong', code on instructions such as ADD ESP,8. This is a deliberate design feature, connected to predictability of output: NASM, on seeing ADD ESP,8, will generate the form of the instruction which leaves room for a 32-bit offset. You need to code ADD ESP,BYTE 8 if you want the space-efficient form of the instruction. This isn't a bug: at worst it's a misfeature, and that's a matter of opinion only.

10.1.2 My Jumps are Out of Range

Similarly, people complain that when they issue conditional jumps (which are SHORT by default) that try to jump too far, NASM reports `short jump out of range' instead of making the jumps longer.

This, again, is partly a predictability issue, but in fact has a more practical reason as well. NASM has no means of being told what type of processor the code it is generating will be run on; so it cannot decide for itself that it should generate Jcc NEAR type instructions, because it doesn't know that it's working for a 386 or above. Alternatively, it could replace the out-of-range short JNE instruction with a very short JE instruction that jumps over a JMP NEAR; this is a sensible solution for processors below a 386, but hardly efficient on processors which have good branch prediction and could have used JNE NEAR instead. So, once again, it's up to the user, not the assembler, to decide what instructions should be generated.

10.1.3 ORG Doesn't Work

People writing boot sector programs in the bin format often complain that ORG doesn't work the way they'd like: in order to place the 0xAA55 signature word at the end of a 512-byte boot sector, people who are used to MASM tend to code

          ORG 0 
          ; some boot sector code 
          ORG 510 
          DW 0xAA55

This is not the intended use of the ORG directive in NASM, and will not work. The correct way to solve this problem in NASM is to use the TIMES directive, like this:

          ORG 0 
          ; some boot sector code 
          TIMES 510-($-$$) DB 0 
          DW 0xAA55

The TIMES directive will insert exactly enough zero bytes into the output to move the assembly point up to 510. This method also has the advantage that if you accidentally fill your boot sector too full, NASM will catch the problem at assembly time and report it, so you won't end up with a boot sector that you have to disassemble to find out what's wrong with it.

10.1.4 TIMES Doesn't Work

The other common problem with the above code is people who write the TIMES line as

          TIMES 510-$ DB 0

by reasoning that $ should be a pure number, just like 510, so the difference between them is also a pure number and can happily be fed to TIMES.

NASM is a modular assembler: the various component parts are designed to be easily separable for re-use, so they don't exchange information unnecessarily. In consequence, the bin output format, even though it has been told by the ORG directive that the .text section should start at 0, does not pass that information back to the expression evaluator. So from the evaluator's point of view, $ isn't a pure number: it's an offset from a section base. Therefore the difference between $ and 510 is also not a pure number, but involves a section base. Values involving section bases cannot be passed as arguments to TIMES.

The solution, as in the previous section, is to code the TIMES line in the form

          TIMES 510-($-$$) DB 0

in which $ and $$ are offsets from the same section base, and so their difference is a pure number. This will solve the problem and generate sensible code.

10.2 Bugs

We have never yet released a version of NASM with any known bugs. That doesn't usually stop there being plenty we didn't know about, though. Any that you find should be reported to hpa@zytor.com.

Please read section 2.2 first, and don't report the bug if it's listed in there as a deliberate feature. (If you think the feature is badly thought out, feel free to send us reasons why you think it should be changed, but don't just send us mail saying `This is a bug' if the documentation says we did it on purpose.) Then read section 10.1, and don't bother reporting the bug if it's listed there.

If you do report a bug, please give us all of the following information:

Next Chapter | Previous Chapter | Contents | Index