Debugging / Unexpected NASMs
Visitors to VTC.com will be able to view all introductory videos for each training course.
Free Trial Members will gain access to first three chapters for each training course.
Full Access Members have full access to VTC.com’s entire library of video tutorials.
Learn More
Subtitles of the Movie
Some things happen over and over again. Some common problems have been reported that are not really problems. They are valid but unexpected actions on the part of the assembler. For example, a report often comes in that NASM is producing inefficient or even erroneous code for certain operands. This instruction is an example. The coded it generates includes a 32-bit constant value for the number eight. The assembler looks at the instruction, see the 32-bit register and produces 32-bit code all around. Now, if you want a shorter version of this instruction, you need to specify the length of the constant value. It isn't a bug; it's a matter of the assembler using the instruction that is most likely the one that the user wanted to specify. Another similar complaint has to do with the jump instruction. By default, jump instruction generate code for short jumps. That is, the target of the jump must be within 127 bytes or the assembler generates an error. Now, there are two possible solutions to this problem but the assembler has no way of determining which one will be appropriate. The simplest solution is to add the word near to the instruction, which causes the assembler to generate code that will jump to an address defined by a 32-bit value. But this longer form of the instruction is not available to all systems. If you want your code to run on a 386, you can write the same thing by using a jump not equal instruction, which is also a short jump to jump over a simple jump instruction, which always uses the long form of address. One problem; two possible solutions. So it's up to the programmer to decide what to do. But you can control whether the long form or the short form is the default. On the Command Line, if you specify the O0 option, there is no optimization. Generating code will take the long forms unless a short form is specified. This, however, does not apply to the conditional jumps. If you specify the O1 option, any constant that will fit into a signed byte are by default reduced to that one byte and conditional jumps default to the long form so they will always works. The third option is the multi-pass option. It can be specified as any number greater than one or by the letter X. It will adjust the size of the jump statements even in the presence of code that specifies otherwise. This last one is the preferred solution in most cases. The Org instruction may not work the way you expect it to. For example, the last word of a 512-byte boot sector is the signature word and contains a specific value. Code like this, written to put the value at this specific point, won't work. Org was not designed to work this way. What you need to do instead is declare a block of data to fill the space in front of the value so it will come out at the right place. But the problem is that to figure out the size of the block, it's necessary to figure out the size of the code. It will be better to have the assembler determine that size for you automatically, which you can do like this. Writing the expression this way brings up another common problem; the times prefix. At first it may look like you want to write the code this way but that won't work because the number on the times statement must be a constant and the dollar symbol is a re-locatable address. It's the address of the current location. What you need instead is a count of the number of bytes from the top of the current segment. The solution is based on the fact that if you subtract two re-locatable addresses in the same segment, you will get a constant. The dollar symbol is the current location in the segment and the double dollar symbol is the address of the first byte of the segment so the difference between the two is a constant count of the number of bytes from the top of the segment to the current location. Subtracting that constant from 510 gives the correct number of fill bytes to align the value to the last word of the block. A few other things may appear at first to be bugs in the assembler but they're really design decisions. NASM is case sensitive. If you use lowercase when defining assemble, it is necessary to use lowercase when you refer to it. When you are referring to the contents of a memory location, you must use square brackets. This was a design decision made to simplify and clarify the syntax. Any time you refer to memory without square brackets, you get the address of that location, not its contents. There are other differences between NASM and other assemblers. More on the other assemblers in later lessons.
Tutorial Information
| Course: | Assembly Language Programming |
| Author: | Arthur Griffith |
| SKU: | 33995 |
| ISBN: | 1-935320-44-0 |
| Release Date: | 2009-05-28 |
| Duration: | 5.5 hrs / 70 lessons |
| Work Files: |
Yes |
| Captions: | Available on CD and Online University |
| Compatibility: |
Vista/XP/2000, OS X, Linux QuickTime 7, Flash 8 |
VTC Sign up & Benefits
- Unlimited Access
- 98,729 Video Tutorials (23,265 free)
- Video Available as Flash or QuickTime
- Over 1026 Courses
- $30 for One Month Access
- Multi-User Discounts Available
United States 