6.0 Comments
Comments in an assembly language program generally come in two forms: endline
comments and standalone comments[14]. As their names
suggest, endline lines comments always occur at the end of a source statement
and standalone comments sit on a line by themselves[15]. These two types of comments have distinct
purposes, this section will explore their use and describe the attributes of a
well-commented program.
6.1 What is a Bad Comment?
It is amazing how many programmers claim their code is well-commented. Were
you to count characters between (or after) the comment delimiters, they might
have a point. Consider, however, the following comment:
mov ax, 0 ;Set AX to zero.
Quite frankly, this comment is worse than no comment at all. It doesn't tell
the reader anything the instruction itself doesn't tell and it requires the
reader to take some of his or her precious time to figure out that the comment
is worthless. If someone cannot tell that this instruction is setting AX to
zero, they have no business reading an assembly language program. This brings up
the first guideline of this section:
- Guideline:
- Choose an intended audience for your source code and write the comments to
that audience. For assembly language source code, you can usually assume the
target audience are those who know a reasonable amount of assembly language.
Don't explain the actions of an assembly language instruction in your code
unless that instruction is doing something that isn't obvious (and most of the
time you should consider changing the code sequence if it isn't obvious what is
going on). Instead, explain how that instruction is helping to solve the problem
at hand. The following is a much better comment for the instruction above:
mov ax, 0 ;AX is the resulting sum. Initialize it.
Note that the comment does not say "Initialize it to zero." Although there
would be nothing intrinsically wrong with saying this, the phrase "Initialize
it" remains true no matter what value you assign to AX. This makes maintaining
the code (and comment) much easier since you don't have to change the comment
whenever you change the constant associated with the instruction.
- Guideline:
- Write your comments in such a way that minor changes to the instruction do
not require that you change the corresponding comment.
Note: Although a trivial comment is bad (indeed, worse than no comment at
all), the worst comment a program can have is one that is wrong. Consider the
following statement:
mov ax, 1 ;Set AX to zero.
It is amazing how long a typical person will look at this code trying to
figure out how on earth the program sets AX to zero when it's obvious it does
not do this. People will always believe comments over code. If there is some
ambiguity between the comments and the code, they will assume that the code is
tricky and that the comments are correct. Only after exhausting all possible
options is the average person likely to concede that the comment must be
incorrect.
- Enforced Rule:
- Never allow incorrect comments in your program.
This is another reason not to put trivial comments like "Set AX to zero" in
your code. As you modify the program, these are the comments most likely to
become incorrect as you change the code and fail to keep the comments in sync.
However, even some non-trivial comments can become incorrect via changes to the
code. Therefore, always follow this rule:
- Enforced Rule:
- Always update all comments affected by a code change immediately after
making the code change.
Undoubtedly you've heard the phrase "make sure you comment your code as
though someone else wrote it for you; otherwise in six months you'll wish you
had." This statement encompasses two concepts. First, don't ever think that your
understanding of the current code will last. While working on a given section of
a program you're probably investing considerable thought and study to figure out
what's going on. Six months down the road, however, you will have forgotten much
of what you figured out and the comments can go a long way to getting you back
up to speed quickly. The second point this code makes is the implication that
others read and write code too. You will have to read someone else's code, they
will have to read yours. If you write the comments the way you would expect
others to write it for you, chances are pretty good that your comments will work
for them as well.
- Rule:
- Never use racist, sexist, obscene, or other exceptionally politically
incorrect language in your comments. Undoubtedly such language in your
comments will come back to embarass you in the future. Furthermore, it's
doubtful that such language would help someone better understand the program.
It's much easier to give examples of bad comments than it is to discuss good
comments. The following list describes some of the worst possible comments you
can put in a program (from worst up to barely tolerable):
- The absolute worst comment you can put into a program is an incorrect
comment. Consider the following assembly statement:
mov ax, 10; { Set AX to 11 }
- It is amazing how many programmers will automatically assume the comment
is correct and try to figure out how this code manages to set the variable "A"
to the value 11 when the code so obviously sets it to 10.
- The second worst comment you can place in a program is a comment that
explains what a statement is doing. The typical example is something like "mov
ax, 10; { Set 'A' to 10 }". Unlike the previous example, this comment is
correct. But it is still worse than no comment at all because it is redundant
and forces the reader to spend additional time reading the code (reading time
is directly proportional to reading difficulty). This also makes it harder to
maintain since slight changes to the code (e.g., "mov ax, 9") requires
modifications to the comment that would not otherwise be required.
- The third worst comment in a program is an irrelevant one. Telling a joke,
for example, may seem cute, but it does little to improve the readability of a
program; indeed, it offers a distraction that breaks concentration.
- The fourth worst comment is no comment at all.
- The fifth worst comment is a comment that is obsolete or out of date
(though not incorrect). For example, comments at the beginning of the file may
describe the current version of a module and who last worked on it. If the
last programmer to modify the file did not update the comments, the comments
are now out of date.
-
6.2 What is a Good Comment?
Steve McConnell provides a long list of suggestions for high-quality code.
These suggestions include:
- Use commenting styles that don't break down or discourage modification.
Essentially, he's saying pick a commenting style that isn't so much work
people refuse to use it. He gives an example of a block of comments surrounded
by asterisks as being hard to maintain. This is a poor example since modern
text editors will automatically "outline" the comments for you. Nevertheless,
the basic idea is sound.
- Comment as you go along. If you put commenting off until the last moment,
then it seems like another task in the software development process always
comes along and management is likely to discourage the completion of the
commenting task in hopes of meeting new deadlines.
- Avoid self-indulgent comments. Also, you should avoid sexist, profane, or
other insulting remarks in your comments. Always remember, someone else will
eventually read your code.
- Avoid putting comments on the same physical line as the statement they
describe. Such comments are very hard to maintain since there is very little
room. McConnell suggests that endline comments are okay for variable
declarations. For some this might be true but many variable declarations may
require considerable explanation that simply won't fit at the end of a line.
One exception to this rule is "maintenance notes." Comments that refer to a
defect tracking entry in the defect database are okay (note that the
CodeWright text editor provides a much better solution for this -- buttons
that can bring up an external file). Of course, endline comments are
marginally more useful in assembly language than in the HLLs that McConnell
addresses, but the basic idea is sound.
- Write comments that describe blocks of statements rather than individual
statements. Comments covering single statements tend to discuss the mechanics
of that statement rather than discussing what the program is doing.
- Focus paragraph comments on the why rather than the how. Code should
explain what the program is doing and why the programmer chose to do it that
way rather than explain what each individual statement is doing.
- Use comments to prepare the reader for what is to follow. Someone reading
the comments should be able to have a good idea of what the following code
does without actually looking at the code. Note that this rule also suggests
that comments should always precede the code to which they apply.
- Make every comment count. If the reader wastes time reading a comment of
little value, the program is harder to read; period.
- Document surprises and tricky code. Of course, the best solution is not to
have any tricky code. In practice, you can't always achieve this goal. When
you do need to restore to some tricky code, make sure you fully document what
you've done.
- Avoid abbreviations. While there may be an argument for abbreviating
identifiers that appear in a program, no way does this apply to comments.
- Keep comments close to the code they describe. The prologue to a program
unit should give its name, describe the parameters, and provide a short
description of the program. It should not go into details about the operation
of the module itself. Internal comments should to that.
- Comments should explain the parameters to a function, assertions about
these parameters, whether they are input, output, or in/out parameters.
- Comments should describe a routine's limitations, assumptions, and any
side effects.
- Rule:
- All comments will be high-quality comments that describe the actions of
the surrounding code in a concise manner
6.3 Endline vs. Standalone Comments
- Guideline:
- Whenever a comment appears on a line by itself, always put the semicolon
in column one. You may indent the text if this is appropriate or aesthetic.
- Guideline:
- Adjacent lines of comments should not have any interspersed blank lines. A
blank comment line should, at least, contain a semicolon in column one.
The guidline above suggests that your code should look like this:
; This is a comment with a blank line between it and the next comment.
;
; This is another line with a comment on it.
Rather than like this:
; This is a comment with a blank line between it and the next comment.
; This is another line with a comment on it.
The semicolon appearing between the two statements suggest continuity that is
not present when you remove the semicolon. If two blocks of comments are truly
separate and whitespace between them is appropriate, you should consider
separating them by a large number of blank lines to completely eliminate any
possible association between the two.
Standalone comments are great for describing the actions of the code that
immediately follows. So what are endline comments useful for? Endline comments
can explain how a sequence of instructions are implimenting the algorithm
described in a previous set of standalone comments. Consider the following
code:
; Compute the transpose of a matrix using the algorithm:
;
; for i := 0 to 3 do
; for j := 0 to 3 do
; swap( a[i][j], b[j][i] );
forlp i, 0, 3
forlp j, 0, 3
mov bx, i ;Compute address of a[i][j] using
shl bx, 2 ; row major ordering (i*4 + j)*2.
add bx, j
add bx, bx
lea bx, a[bx]
push bx ;Push address of a[i][j] onto
stack.
mov bx, j ;Compute address of b[j][i] using
shl bx, 2 ;row major ordering (j*4 + i)*2.
add bx, i
add bx, bx
lea bx, b[bx]
push bx ;Push address of b[j][i] onto
stack.
call swap ;Swap a[i][j] with b[j][i].
next
next
Note that the block comments before this sequence explain, in high level
terms, what the code is doing. The endline comments explain how the statement
sequence implements the general algorithm. Note, however, that the endline
comments do not explain what each statement is doing (at least at the machine
level). Rather than claiming "add bx, bx" is multiplying the quantity in BX by
two, this code assumes the reader can figure that out for themselves (any
reasonable assembly programmer would know this). Once again, keep in mind your
audience and write your comments for them.
6.4 Unfinished Code
Often it is the case that a programmer will write a section of code that
(partially) accomplishes some task but needs further work to complete a feature
set, make it more robust, or remove some known defect in the code. It is common
for such programmers to place comments into the code like "This needs more
work," "Kludge ahead," etc. The problem with these comments is that they are
often forgotten. It isn't until the code fails in the field that the section of
code associated with these comments is found and their problems corrected.
Ideally, one should never have to put such code into a program. Of course,
ideally, programs never have any defects in them, either. Since such code
inevitably finds its way into a program, it's best to have a policy in place to
deal with it, hence this section.
Unfinished code comes in five general categories: non-functional code,
partially functioning code, suspect code, code in need of enhancement, and code
documentation. Non-functional code might be a stub or driver that needs to be
replaced in the future with actual code or some code that has severe enough
defects that it is useless except for some small special cases. This code is
really bad, fortunately its severity prevents you from ignoring it. It is
unlikely anyone would miss such a poorly constructed piece of code in early
testing prior to release.
Partially functioning code is, perhaps, the biggest problem. This code works
well enough to pass some simple tests yet contains serious defects that should
be corrected. Moreover, these defects are known. Software often contains a large
number of unknown defects; it's a shame to let some (prior) known defects ship
with the product simply because a programmer forgot about a defect or couldn't
find the defect later.
Suspect code is exactly that- code that is suspicious. The programmer may not
be aware of a quantifiable problem but may suspect that a problem exists. Such
code will need a later review in order to verify whether it is correct.
The fourth category, code in need of enhancement, is the least serious. For
example, to expedite a release, a programmer might choose to use a simple
algorithm rather than a complex, faster algorithm. S/he could make a comment in
the code like "This linear search should be replaced by a hash table lookup in a
future version of the software." Although it might not be absolutely necessary
to correct such a problem, it would be nice to know about such problems so they
can be dealt with in the future.
The fifth category, documentation, refers to changes made to software that
will affect the corresponding documentation (user guide, design document, etc.).
The documentation department can search for these defects to bring existing
documentation in line with the current code.
This standard defines a mechanism for dealing with these five classes of
problems. Any occurrence of unfinished code will be preceded by a comment that
takes one of the following forms (where "_" denotes a single space):
;_#defect#severe_;
;_#defect#functional_;
;_#defect#suspect_;
;_#defect#enhancement_;
;_#defect#documentation_;
It is important to use all lower case and verify the correct spelling so it
is easy to find these comments using a text editor search or a tool like grep.
Obviously, a separate comment explaining the situation must follow these
comments in the source code.
Examples:
; #defect#suspect ;
; #defect#enhancement ;
; #defect#documentation ;
Notice the use of comment delimiters (the semicolon) on both sides even
though assembly language, doesn't require them.
- Enforced Rule:
- If a module contains some defects that cannot be immediately removed
because of time or other constraints, the program will insert a standardized
comment before the code so that it is easy to locate such problems in the
future. The five standardized comments are ";_#defect#severe_;,
";_#defect#functional_;", ";_#defect#suspect_;", ";_#defect#enhancement_;",
and ";_#defect#documentation_;" where "_" denotes a single space. The spelling
and spacing should be exact so it is easy to search for these strings in the
source tree.
6.5 Cross References in Code to Other Documents
In many instances a section of code might be intrinsically tied to some other
document. For example, you might refer the reader to the user document or the
design document within your comments in a program. This document proposes a
standard way to do this so that it is relatively easy to locate cross references
appearing in source code. The technique is similar to that for defect reporting,
except the comments take the form:
; text #link#location text ;
"Text" is optional and represents arbitrary text (although it is really
intended for embedding html commands to provide hyperlinks to the specified
document). "Location" describes the document and section where the associated
information can be found.
Examples:
; #link#User's Guide Section 3.1 ;
; #link#Program Design Document, Page 5 ;
; #link#Funcs.pas module, "xyz" function ;
; <A HREF="DesignDoc.html#xyzfunc"> #link#xyzfunc
</a> ;
- Guideline:
- If a module contains some cross references to other documents, there
should be a comment that takes the form "; text #link#location text ;" that
provides the reference to that other document. In this comment "text"
represents some optional text (typically reserved for html tags) and
"location" is some descriptive text that describes the document (and a
position in that document) related to the current section of code in the
program.
|