| \C{trouble} Troubleshooting |
| |
| This chapter describes some of the common problems that users have |
| been known to encounter with NASM, and answers them. If you think you |
| have found a bug in NASM, please see \k{bugs}. |
| |
| |
| \H{problems} Common Problems |
| |
| \S{inefficient} NASM Generates \i{Inefficient Code} |
| |
| We sometimes get `bug' reports about NASM generating inefficient, or |
| even `wrong', code on instructions such as \c{ADD ESP,8}. This is a |
| deliberate design feature, connected to predictability of output: |
| NASM, on seeing \c{ADD ESP,8}, will generate the form of the |
| instruction which leaves room for a 32-bit offset. You need to code |
| \I\c{BYTE}\c{ADD ESP,BYTE 8} if you want the space-efficient form of |
| the instruction. This isn't a bug, it's user error: if you prefer to |
| have NASM produce the more efficient code automatically enable |
| optimization with the \c{-O} option (see \k{opt-O}). |
| |
| |
| \S{jmprange} My Jumps are Out of Range\I{out of range, jumps} |
| |
| Similarly, people complain that when they issue \i{conditional |
| jumps} (which are \c{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 \i\c{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 |
| \c{JNE} instruction with a very short \c{JE} instruction that jumps |
| over a \c{JMP NEAR}; this is a sensible solution for processors |
| below a 386, but hardly efficient on processors which have good |
| branch prediction \e{and} could have used \c{JNE NEAR} instead. So, |
| once again, it's up to the user, not the assembler, to decide what |
| instructions should be generated. See \k{opt-O}. |
| |
| |
| \S{proborg} \i\c{ORG} Doesn't Work |
| |
| People writing \i{boot sector} programs in the \c{bin} format often |
| complain that \c{ORG} doesn't work the way they'd like: in order to |
| place the \c{0xAA55} signature word at the end of a 512-byte boot |
| sector, people who are used to MASM tend to code |
| |
| \c ORG 0 |
| \c |
| \c ; some boot sector code |
| \c |
| \c ORG 510 |
| \c DW 0xAA55 |
| |
| This is not the intended use of the \c{ORG} directive in NASM, and |
| will not work. The correct way to solve this problem in NASM is to |
| use the \i\c{TIMES} directive, like this: |
| |
| \c ORG 0 |
| \c |
| \c ; some boot sector code |
| \c |
| \c TIMES 510-($-$$) DB 0 |
| \c DW 0xAA55 |
| |
| The \c{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. |
| |
| |
| \S{probtimes} \i\c{TIMES} Doesn't Work |
| |
| The other common problem with the above code is people who write the |
| \c{TIMES} line as |
| |
| \c TIMES 510-$ DB 0 |
| |
| by reasoning that \c{$} should be a pure number, just like 510, so |
| the difference between them is also a pure number and can happily be |
| fed to \c{TIMES}. |
| |
| NASM is a \e{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 \c{bin} output |
| format, even though it has been told by the \c{ORG} directive that |
| the \c{.text} section should start at 0, does not pass that |
| information back to the expression evaluator. So from the |
| evaluator's point of view, \c{$} isn't a pure number: it's an offset |
| from a section base. Therefore the difference between \c{$} and 510 |
| is also not a pure number, but involves a section base. Values |
| involving section bases cannot be passed as arguments to \c{TIMES}. |
| |
| The solution, as in the previous section, is to code the \c{TIMES} |
| line in the form |
| |
| \c TIMES 510-($-$$) DB 0 |
| |
| in which \c{$} and \c{$$} are offsets from the same section base, |
| and so their difference is a pure number. This will solve the |
| problem and generate sensible code. |
| |