Rewrite and rearrange some rgbasm docs

This commit is contained in:
Rangi42
2024-08-27 00:48:49 -04:00
parent b77ba1d87d
commit de84e3ea8b

View File

@@ -175,11 +175,8 @@ or
If specified, prints this character in front of non-negative numbers. If specified, prints this character in front of non-negative numbers.
.It Ql <prefix> Ta May be .It Ql <prefix> Ta May be
.Ql # . .Ql # .
If specified, prints the appropriate prefix for numbers, If specified, prints a base prefix for non-decimal integer types
.Ql $ , .Pq So $ Sc , So & Sc , or So % Sc .
.Ql & ,
or
.Ql % .
.It Ql <align> Ta May be .It Ql <align> Ta May be
.Ql - . .Ql - .
If specified, aligns left instead of right. If specified, aligns left instead of right.
@@ -197,7 +194,7 @@ followed by one or more
.Ql 0 .Ql 0
\[en] \[en]
.Ql 9 . .Ql 9 .
If specified, prints this many digits of a fixed-point fraction. If specified, prints this many fractional digits of a fixed-point number.
Defaults to 5 digits, maximum 255 digits. Defaults to 5 digits, maximum 255 digits.
.It Ql <type> Ta Specifies the type of value. .It Ql <type> Ta Specifies the type of value.
.El .El
@@ -205,8 +202,8 @@ Defaults to 5 digits, maximum 255 digits.
All the format specifier parts are optional except the All the format specifier parts are optional except the
.Ql <type> . .Ql <type> .
Valid print types are: Valid print types are:
.Bl -column -offset indent "Print type" "Lowercase hexadecimal" "Example" .Bl -column -offset indent "Type" "Lowercase hexadecimal" "Example"
.It Sy Print type Ta Sy Format Ta Sy Example .It Sy Type Ta Sy Format Ta Sy Example
.It Ql d Ta Signed decimal Ta -42 .It Ql d Ta Signed decimal Ta -42
.It Ql u Ta Unsigned decimal Ta 42 .It Ql u Ta Unsigned decimal Ta 42
.It Ql x Ta Lowercase hexadecimal Ta 2a .It Ql x Ta Lowercase hexadecimal Ta 2a
@@ -214,7 +211,7 @@ Valid print types are:
.It Ql b Ta Binary Ta 101010 .It Ql b Ta Binary Ta 101010
.It Ql o Ta Octal Ta 52 .It Ql o Ta Octal Ta 52
.It Ql f Ta Fixed-point Ta 1234.56789 .It Ql f Ta Fixed-point Ta 1234.56789
.It Ql s Ta String Ta \&"example\&" .It Ql s Ta String Ta string contents
.El .El
.Pp .Pp
Examples: Examples:
@@ -515,21 +512,17 @@ is special in that it causes the character following it to be
.Dq escaped , .Dq escaped ,
meaning that it is treated differently from normal. meaning that it is treated differently from normal.
There are a number of escape sequences you can use within a string: There are a number of escape sequences you can use within a string:
.Bl -column -offset indent "Qo \e1 Qc \[en] Qo \e9 Qc" .Bl -column -offset indent "Sequence"
.It Sy String Ta Sy Meaning .It Sy Sequence Ta Sy Meaning
.It Ql \e\e Ta Produces a backslash .It Ql \e\e Ta Backslash Pq escapes the escape character itself
.It Ql \e" Ta Produces a double quote without terminating .It Ql \e" Ta Double quote Pq does not terminate the string
.It Ql \e{ Ta Curly bracket left .It Ql \e{ Ta Open curly brace Pq does not start interpolation
.It Ql \e} Ta Curly bracket right .It Ql \e} Ta Close curly brace Pq does not end interpolation
.It Ql \en Ta Newline ($0A) .It Ql \en Ta Newline Pq ASCII $0A
.It Ql \er Ta Carriage return ($0D) .It Ql \er Ta Carriage return Pq ASCII $0D
.It Ql \et Ta Tab ($09) .It Ql \et Ta Tab Pq ASCII $09
.It Ql \e0 Ta Null ($00) .It Ql \e0 Ta Null Pq ASCII $00
.It Qo \e1 Qc \[en] Qo \e9 Qc Ta Macro argument Pq Only in the body of a macro; see Sx Invoking macros
.It Ql \e# Ta All Dv _NARG No macro arguments, separated by commas Pq Only in the body of a macro
.It Ql \e@ Ta Label name suffix Pq Only in the body of a macro or a Ic REPT No block
.El .El
(Note that some of those can be used outside of strings, when noted further in this document.)
.Pp .Pp
Multi-line strings are contained in triple quotes Multi-line strings are contained in triple quotes
.Pq Ql \&"\&"\&"for instance\&"\&"\&" . .Pq Ql \&"\&"\&"for instance\&"\&"\&" .
@@ -821,6 +814,7 @@ Section examples:
.Bd -literal -offset indent .Bd -literal -offset indent
SECTION "Cool Stuff", ROMX SECTION "Cool Stuff", ROMX
.Ed .Ed
.Pp
This switches to the section called This switches to the section called
.Dq CoolStuff , .Dq CoolStuff ,
creating it if it doesn't already exist. creating it if it doesn't already exist.
@@ -1341,9 +1335,9 @@ below).
is used to define string constant symbols. is used to define string constant symbols.
Wherever the assembler reads a string constant, it gets Wherever the assembler reads a string constant, it gets
.Em expanded : .Em expanded :
the symbol's name is replaced with its contents. the symbol's name is replaced with its contents, similarly to
If you are familiar with C, you can think of it as similar to .Ic #define
.Fd #define . in the C programming language.
This expansion is disabled in a few contexts: This expansion is disabled in a few contexts:
.Ql DEF(name) , .Ql DEF(name) ,
.Ql DEF name EQU/=/EQUS/etc ... , .Ql DEF name EQU/=/EQUS/etc ... ,
@@ -1389,38 +1383,35 @@ PRINTLN "{s}\en"
String constants can't be exported or imported. String constants can't be exported or imported.
.Pp .Pp
.Sy Important note : .Sy Important note :
When a string constant is expanded, its expansion may contain another string constant, which will be expanded as well. When a string constant is expanded, its expansion may contain another string constant, which will be expanded as well, and may be recursive.
If this creates an infinite loop, If this creates an infinite loop,
.Nm .Nm
will error out once a certain depth is will error out once a certain depth is
reached. reached (see the
See the
.Fl r .Fl r
command-line option in command-line option in
.Xr rgbasm 1 . .Xr rgbasm 1 ) .
The same problem can occur if the expansion of a macro invokes another macro, recursively. The same problem can occur if the expansion of a string constant invokes a macro, which itself expands.
.Ss Macros .Ss Macros
One of the best features of an assembler is the ability to write macros for it. One of the best features of an assembler is the ability to write macros for it.
Macros can be called with arguments, and can react depending on input using Macros can be called with arguments, and can react depending on input using
.Ic IF .Ic IF
constructs. constructs.
.Bd -literal -offset indent .Bd -literal -offset indent
MACRO MyMacro MACRO my_macro
ld a, 80 ld a, 80
call MyFunc call MyFunc
ENDM ENDM
.Ed .Ed
.Pp .Pp
The example above defines The example above defines
.Ql MyMacro .Ql my_macro
as a new macro. as a new macro.
String constants are not expanded within the name of the macro. String constants are not expanded within the name of the macro.
.Pp .Pp
Macros can't be exported or imported. Macros can't be exported or imported.
.Pp .Pp
Plainly nesting macro definitions is not allowed, but this can be worked around using Nesting macro definitions is not possible, so this won't work:
.Ic EQUS .
So this won't work:
.Bd -literal -offset indent .Bd -literal -offset indent
MACRO outer MACRO outer
MACRO inner MACRO inner
@@ -1429,22 +1420,20 @@ MACRO outer
ENDM ; ...and then this is a syntax error! ENDM ; ...and then this is a syntax error!
.Ed .Ed
.Pp .Pp
But this will: But you can work around this limitation using
.Ic EQUS ,
so this will work:
.Bd -literal -offset indent .Bd -literal -offset indent
MACRO outer MACRO outer
DEF definition EQUS "MACRO inner\enPRINTLN \e"Hello!\e"\enENDM" DEF definition EQUS "MACRO inner\enPRINTLN \e"Hello!\e"\enENDM"
definition definition
PURGE definition PURGE definition
ENDM ENDM
.Ed .Ed
.Pp .Pp
Macro arguments support all the escape sequences of strings, as well as More about how to define and invoke macros is described in
.Ql \e, .Sx THE MACRO LANGUAGE
to escape commas, as well as below.
.Ql \e(
and
.Ql \e)
to escape parentheses, since those otherwise separate and enclose arguments, respectively.
.Ss Exporting and importing symbols .Ss Exporting and importing symbols
Importing and exporting of symbols is a feature that is very useful when your project spans many source files and, for example, you need to jump to a routine defined in another file. Importing and exporting of symbols is a feature that is very useful when your project spans many source files and, for example, you need to jump to a routine defined in another file.
.Pp .Pp
@@ -1739,114 +1728,89 @@ Unions may be used in any section, but they may only contain space-allocating di
.Sx Statically allocating space in RAM ) . .Sx Statically allocating space in RAM ) .
.Sh THE MACRO LANGUAGE .Sh THE MACRO LANGUAGE
.Ss Invoking macros .Ss Invoking macros
A macro is invoked by writing its name at the beginning of a line, followed by any arguments. A macro is invoked by using its name at the beginning of a line, like a directive, followed by any comma-separated arguments.
.Bd -literal -offset indent .Bd -literal -offset indent
add a, b add a, b
ld sp, hl ld sp, hl
MyMacro ;\ This will be expanded my_macro ;\ This will be expanded
sub a, 87 sub a, 87
MyMacro 42 ;\ So will this my_macro 42 ;\ So will this
ret c
my_macro 1, 2 ;\ And this
.Ed .Ed
.Pp .Pp
It's valid to call a macro from a macro (yes, even the same one). After
.Pp
When
.Nm .Nm
sees has read the macro invocation line, it will expand the body of the macro (the lines between
.Ic MyMacro
it will insert the macro definition (the code enclosed in
.Ic MACRO .Ic MACRO
/ and
.Ic ENDM ) . .Ic ENDM )
.Pp in its place.
Suppose your macro contains a loop.
.Bd -literal -offset indent
MACRO LoopyMacro
xor a, a
\&.loop
ld [hl+], a
dec c
jr nz, .loop
ENDM
.Ed
.Pp
This is fine, but only if you use the macro no more than once per scope.
To get around this problem, there is the escape sequence
.Ic \e@
that expands to a unique string.
.Pp
.Ic \e@
also works in
.Ic REPT
blocks.
.Bd -literal -offset indent
MACRO LoopyMacro
xor a, a
\&.loop\e@
ld [hl+], a
dec c
jr nz, .loop\e@
ENDM
.Ed
.Pp .Pp
.Sy Important note : .Sy Important note :
Since a macro can call itself (or a different macro that calls the first one), there can be circular dependency problems. When a macro body is expanded, its expansion may contain another macro invocation, which will be expanded as well, and may be recursive.
If this creates an infinite loop, If this creates an infinite loop,
.Nm .Nm
will error out once a certain depth is will error out once a certain depth is
reached. reached (see the
See the
.Fl r .Fl r
command-line option in command-line option in
.Xr rgbasm 1 . .Xr rgbasm 1 ) .
Also, a macro can have inside an The same problem can occur if the expansion of a macro then expands a string constant, which itself expands.
.Sy EQUS
which references the same macro, which has the same problem.
.Pp .Pp
It's possible to pass arguments to macros as well! It's possible to pass arguments to macros as well!
You retrieve the arguments by using the escape sequences .Bd -literal -offset indent
MACRO lb
ld \e1, (\e2) << 8 | (\e3)
ENDM
lb hl, 20, 18 ; Expands to "ld hl, ((20) << 8) | (18)"
lb de, 3 + 1, NUM**2 ; Expands to "ld de, ((3 + 1) << 8) | (NUM**2)"
.Ed
.Pp
You expand the arguments inside the macro body by using the escape sequences
.Ic \e1 .Ic \e1
through through
.Ic \e9 , \e1 .Ic \e9 , \e1
being the first argument specified on the macro invocation. being the first argument,
.Bd -literal -offset indent .Ic \e2
MACRO LoopyMacro being the second, and so on. Since there are only nine digits, you can only use the first nine macro arguments that way.
ld hl, \e1 To use the rest, you put the argument number in angle brackets, like
ld c, \e2 .Ic \e<10> .
xor a, a
\&.loop\e@
ld [hl+], a
dec c
jr nz, .loop\e@
ENDM
.Ed
.Pp .Pp
Now you can call the macro specifying two arguments, the first being the address and the second being a byte count. This bracketed syntax supports decimal numbers and numeric constant symbols.
The generated code will then reset all bytes in this range. For example,
.Bd -literal -offset indent .Ql \e<_NARG>
LoopyMacro MyVars, 54 will get the last argument.
.Ed
.Pp .Pp
Arguments are passed as string constants, although there's no need to enclose them in quotes. Other macro arguments and symbol interpolations will also be expanded inside the angle brackets.
Thus, an expression will not be evaluated first but kind of copy-pasted. For example, if
This means that it's probably a very good idea to use brackets around .Ql \e1
.Ic \e1 is
to .Ql 13 ,
.Ic \e9 then
if you perform further calculations on them. .Ql \e<\e1>
For instance, consider the following: inside the macro body will expand to
.Bd -literal -offset indent .Ql \e<13> .
MACRO print_double Or if
PRINTLN \e1 * 2 .Ql DEF v10 = 42
ENDM and
print_double 1 + 2 .Ql DEF x = 10 ,
.Ed then
.Ql \e<v{d:x}>
will expand to
.Ql \e<42> .
.Pp .Pp
The Macro arguments are passed as string constants, although there's no need to enclose them in quotes.
.Ic PRINTLN Thus, arguments are not evaluated as expressions, but instead are expanded directly inside the macro body.
statement will expand to This means that they support all the escape sequences of strings (see
.Ql PRINTLN 1 + 2 * 2 , .Sx String expressions
which will print 5 and not 6 as you might have expected. above), as well as some of their own:
.Bl -column -offset indent "Sequence"
.It Sy Sequence Ta Sy Meaning
.It Ql \e, Ta Comma Pq does not terminate the argument
.It Ql \e( Ta Open parenthesis Pq does not start enclosing argument contents
.It Ql \e) Ta Close parenthesis Pq does not end enclosing argument contents
.El
.Pp .Pp
Line continuations work as usual inside macros or lists of macro arguments. Line continuations work as usual inside macros or lists of macro arguments.
However, some characters need to be escaped, as in the following example: However, some characters need to be escaped, as in the following example:
@@ -1868,87 +1832,100 @@ The comma in
needs to be escaped to prevent it from starting another macro argument. needs to be escaped to prevent it from starting another macro argument.
The comma in The comma in
.Ql PrintMacro2 .Ql PrintMacro2
does not need escaping because it is inside parentheses, similar to macro arguments in C. does not need escaping because it is inside parentheses, similar to macro arguments in the C programming language.
The backslash in The backslash in
.Ql \en .Ql \en
also does not need escaping because string literals work as usual inside macro arguments. also does not need escaping because quoted string literals work as usual inside macro arguments.
.Pp .Pp
Since there are only nine digits, you can only access the first nine macro arguments like this. Since macro arguments are expanded directly, it's often a good idea to put parentheses around them if they're meant as part of a numeric expression.
To use the rest, you need to put the multi-digit argument number in angle brackets, like For instance, consider the following:
.Ql \e<10> . .Bd -literal -offset indent
This bracketed syntax supports decimal numbers and numeric constant symbols. MACRO print_double
For example, PRINTLN \e1 * 3
.Ql \e<_NARG> ENDM
will get the last argument. print_double 1 + 2
.Ed
.Pp .Pp
Other macro arguments and symbol interpolations will be expanded inside the angle brackets. The body will expand to
For example, if .Ql PRINTLN 1 + 2 * 3 ,
.Ql \e1 which will print 7 and not 9 as you might have expected.
is
.Ql 13 ,
then
.Ql \e<\e1>
will expand to
.Ql \e<13> .
Or if
.Ql v10 = 42
and
.Ql x = 10 ,
then
.Ql \e<v{d:x}>
will expand to
.Ql \e<42> .
.Pp .Pp
The The
.Ic SHIFT .Ic SHIFT
directive is only available inside macros. directive is only available inside macro bodies.
It will shift the arguments by one to the left, and decrease It shifts the argument numbers by one to the left, so what was
.Dv _NARG
by 1:
.Ic \e1
takes the value of
.Ic \e2 ,
then
.Ic \e2 .Ic \e2
takes the value of is now
.Ic \e3 , .Ic \e1 ,
what was
.Ic \e3
is now
.Ic \e2 ,
and so forth. and so forth.
(What was
.Ic \e1
is no longer accessible, so
.Dv _NARG
is decreased by 1.)
.Pp .Pp
.Ic SHIFT .Ic SHIFT
can optionally be given an integer parameter, and will apply the above shifting that number of times. can also take an integer parameter to shift that many times instead of once.
A negative parameter will shift the arguments in reverse. A negative parameter will shift the arguments to the right, which can regain access to previously shifted ones.
.Pp .Pp
.Ic SHIFT .Ic SHIFT
is especially useful in is especially useful in
.Ic REPT .Ic REPT
loops, to repeat the same commands but with different arguments each time. loops to iterate over different arguments, evaluating the same loop body each time.
.Ss Printing things during assembly .Pp
The There are some escape sequences which are only valid inside the body of a macro:
.Ic PRINT .Bl -column -offset indent "Sequence"
and .It Sy Sequence Ta Sy Meaning
.Ic PRINTLN .It So \e1 Sc \[en] So \e9 Sc Ta The 1st\[en]9th macro argument
commands print text and values to the standard output. .It Ql \e<...> Ta Further macro arguments
Useful for debugging macros, or wherever you may feel the need to tell yourself some important information. .It Ql \e# Ta All Dv _NARG No macro arguments, separated by commas
.Bd -literal -offset indent .It Ql \e@ Ta Unique symbol name affix Pq see below
PRINT "Hello world!\en"
PRINTLN "Hello world!"
PRINT _NARG, " arguments\en"
PRINTLN "sum: ", 2+3, " product: ", 2*3
PRINTLN STRFMT("E = %f", 2.718)
.Ed
.Bl -inset
.It Ic PRINT
prints out each of its comma-separated arguments.
Numbers are printed as unsigned uppercase hexadecimal with a leading
.Sq $ .
For different formats, use
.Ic STRFMT .
.It Ic PRINTLN
prints out each of its comma-separated arguments, if any, followed by a line feed
.Pq Ql \en .
.El .El
.Pp
The
.Ic \e@
escape sequence is often useful in macros which define symbols.
Suppose your macro expands to a loop of assembly code:
.Bd -literal -offset indent
MACRO loop_c_times
xor a, a
\&.loop
ld [hl+], a
dec c
jr nz, .loop
ENDM
.Ed
.Pp
If you use this macro more than once in the same label scope, it will define
.Ql \&.loop
twice, which is an error.
To work around this problem, you can use
.Ic \e@
as a label suffix:
.Bd -literal -offset indent
MACRO loop_c_times_fixed
xor a, a
\&.loop\e@
ld [hl+], a
dec c
jr nz, .loop\e@
ENDM
.Ed
.Pp
This will expand to a different value in each invocation, similar to
.Ic gensym
in the Lisp programming language.
.Pp
.Ic \e@
also works in
.Ic REPT
blocks, expanding to a different value in each iteration.
.Ss Automatically repeating blocks of code .Ss Automatically repeating blocks of code
Suppose you want to unroll a time consuming loop without copy-pasting it. Suppose you want to unroll a time-consuming loop without copy-pasting it.
.Ic REPT .Ic REPT
is here for that purpose. is here for that purpose.
Everything between Everything between
@@ -2016,9 +1993,9 @@ DEF N = 256
.Pp .Pp
You can customize the range of You can customize the range of
.Ic FOR .Ic FOR
values, similarly to Python's values, similarly to the
.Ql range .Ql range
function: function in the Python programming language:
.Bl -column "FOR V, start, stop, step" .Bl -column "FOR V, start, stop, step"
.It Sy Code Ta Sy Range .It Sy Code Ta Sy Range
.It Ic FOR Ar V , stop Ta Ar V No increments from 0 to Ar stop .It Ic FOR Ar V , stop Ta Ar V No increments from 0 to Ar stop
@@ -2100,6 +2077,101 @@ This will print:
.Bd -literal -offset indent .Bd -literal -offset indent
1, 2, 3, 4, 5 stop! done 5 1, 2, 3, 4, 5 stop! done 5
.Ed .Ed
.Ss Conditionally assembling blocks of code
The four commands
.Ic IF , ELIF , ELSE ,
and
.Ic ENDC
let you have
.Nm
skip over parts of your code depending on a condition.
This is a powerful feature commonly used in macros.
.Bd -literal -offset indent
IF NUM < 0
PRINTLN "NUM < 0"
ELIF NUM == 0
PRINTLN "NUM == 0"
ELSE
PRINTLN "NUM > 0"
ENDC
.Ed
.Pp
The
.Ic ELIF
(standing for "else if") and
.Ic ELSE
blocks are optional.
.Ic IF
/
.Ic ELIF
/
.Ic ELSE
/
.Ic ENDC
blocks can be nested.
.Pp
Note that if an
.Ic ELSE
block is found before an
.Ic ELIF
block, the
.Ic ELIF
block will be ignored.
All
.Ic ELIF
blocks must go before the
.Ic ELSE
block.
Also, if there is more than one
.Ic ELSE
block, all of them but the first one are ignored.
.Ss Including other source files
Use
.Ic INCLUDE
to process another assembler file and then return to the current file when done.
If the file isn't found in the current directory, the include path list (see the
.Fl I
option in
.Xr rgbasm 1 )
will be searched.
You may nest
.Ic INCLUDE
calls infinitely (or until you run out of memory, whichever comes first).
.Bd -literal -offset indent
INCLUDE "irq.inc"
.Ed
.Pp
You may also implicitly
.Ic INCLUDE
a file before the source file with the
.Fl P
option of
.Xr rgbasm 1 .
.Ss Printing things during assembly
The
.Ic PRINT
and
.Ic PRINTLN
commands print text and values to the standard output.
Useful for debugging macros, or wherever you may feel the need to tell yourself some important information.
.Bd -literal -offset indent
PRINT "Hello world!\en"
PRINTLN "Hello world!"
PRINT _NARG, " arguments\en"
PRINTLN "sum: ", 2+3, " product: ", 2*3
PRINTLN STRFMT("E = %f", 2.718)
.Ed
.Bl -inset
.It Ic PRINT
prints out each of its comma-separated arguments.
Numbers are printed as unsigned uppercase hexadecimal with a leading
.Sq $ .
For different formats, use
.Ic STRFMT .
.It Ic PRINTLN
prints out each of its comma-separated arguments, if any, followed by a line feed
.Pq Ql \en .
.El
.Ss Aborting the assembly process .Ss Aborting the assembly process
.Ic FAIL .Ic FAIL
and and
@@ -2172,76 +2244,6 @@ to be emitted;
(the default) will cause a non-fatal error; and (the default) will cause a non-fatal error; and
.Ic FATAL .Ic FATAL
immediately aborts. immediately aborts.
.Ss Including other source files
Use
.Ic INCLUDE
to process another assembler file and then return to the current file when done.
If the file isn't found in the current directory, the include path list (see the
.Fl I
option in
.Xr rgbasm 1 )
will be searched.
You may nest
.Ic INCLUDE
calls infinitely (or until you run out of memory, whichever comes first).
.Bd -literal -offset indent
INCLUDE "irq.inc"
.Ed
.Pp
You may also implicitly
.Ic INCLUDE
a file before the source file with the
.Fl P
option of
.Xr rgbasm 1 .
.Ss Conditional assembling
The four commands
.Ic IF , ELIF , ELSE ,
and
.Ic ENDC
let you have
.Nm
skip over parts of your code depending on a condition.
This is a powerful feature commonly used in macros.
.Bd -literal -offset indent
IF NUM < 0
PRINTLN "NUM < 0"
ELIF NUM == 0
PRINTLN "NUM == 0"
ELSE
PRINTLN "NUM > 0"
ENDC
.Ed
.Pp
The
.Ic ELIF
(standing for "else if") and
.Ic ELSE
blocks are optional.
.Ic IF
/
.Ic ELIF
/
.Ic ELSE
/
.Ic ENDC
blocks can be nested.
.Pp
Note that if an
.Ic ELSE
block is found before an
.Ic ELIF
block, the
.Ic ELIF
block will be ignored.
All
.Ic ELIF
blocks must go before the
.Ic ELSE
block.
Also, if there is more than one
.Ic ELSE
block, all of them but the first one are ignored.
.Sh MISCELLANEOUS .Sh MISCELLANEOUS
.Ss Changing options while assembling .Ss Changing options while assembling
.Ic OPT .Ic OPT