SCAS(1)

πŸ“¦ version 0.5.5, in nixos 26.05, nixpkgs unstable

πŸ’… SCAS(1) β€” SirCmpwn's Assembler: the group-chat remix πŸ’…

okay so bestie, welcome to SCAS(1), aka SirCmpwn's Assembler. This is part 1 of the manual, and it's lowkey iconic: assembler, linker, preprocessor, flags, the whole buffet. Let's get into it. ✨

πŸŽ€ NAME πŸŽ€

scas β€” SirCmpwn's Assembler. That's it. That's the name. Slay.

🌸 SYNOPSIS 🌸

scas [options] FILE(s)

πŸ¦‹ DESCRIPTION πŸ¦‹

scas assembles and optionally links any number of assembly and object files into a single output file. If you specify "-" as an input file name, it reads from stdin. Yes, stdin. The dash is the main character. πŸ’…

✨ OPTIONS ✨

  • -a, --architecture <arch> β€” Specifies an architecture or instruction set file. The default is z80. If you specify a file name, that file will be used as an instruction set. Otherwise, it will be matched against scas’s internal list of instruction sets. See Architectures below for additional information.
  • -c, --compile β€” Compile, but do not link, the assembly sources into an object file.
  • -D <MACRO>, -D<MACRO>, --define <MACRO> β€” Defines MACRO as 1. You may also use -D MACRO=STRING to set a macro to a specific value, as if writing #define MACRO STRING into your code.
  • -f<option>[=value] β€” Enables an assembler flag. See Flags below.
  • -i, --input <file> β€” Uses the specified file, or - for stdin, as input.
  • -I, --include <directories> β€” Adds the specified directories to the include path, delimited by commas. By default, the include path is the working directory plus anything in the SCAS_PATH environment variable.
  • -o, --output <file> β€” Uses the specified file, or - for stdout, as the output.
  • -L, --listing <file> β€” Outputs a listing file to file, or - for stdout. This is a human-readable plaintext file that can help you find out more about how the file was assembled. Its format is described in Listings below.
  • -S, --symbols <file> β€” Outputs symbols as assembly source to the specified file, or - for stdout. See Symbol Files below for additional information.
  • -v[vv...] β€” Specifies different levels of log verbosity.
  • --color β€” Colorize log output. This is the default on platforms which use ELF as their file format (Linux).

πŸ”₯ EXAMPLES πŸ”₯

  • scas input.asm output.bin β€” Assembles and links input.asm and produces output.bin as machine code.
  • scas input1.asm input2.asm input3.asm output.bin β€” Assembles and links three input files and produces output.bin as machine code. The default behavior with several files is to arrange their output in order.
  • scas -c screen.asm screen.o β€” Assembles input1.asm and produces an unlinked object file.
  • scas -o game.bin screen.o keyboard.o main.o β€” Links three object files together and produces game.bin as machine code.

🚩 FLAGS 🚩

Flags are enabled with the -f option. You may disable any of these flags by using -fno-[flag] (for example: -fno-remove-unused-funcs to disable the removal of unused functions).

  • -fauto-relocation β€” Disabled by default. Enabling this flag will insert KnightOS relocation instructions before all local references during linking, among other changes. This is generally not recommended because it fails to handle more complex scenarios.
  • -fexplicit-export β€” Disabled by default. Instead of exporting all symbols implicitly, require that all symbols for export are explicitly declared as such through the export directive.
  • -fexplicit-import β€” Disabled by default. Instead of postponing all unresolved symbol errors to the linker, this flag instructs scas to raise errors during assembly if any external symbols are referenced without an import directive.
  • -fformat=<format> β€” bin by default. Outputs machine code in the given format. Available formats:
    • bin β€” Binary machine code
    • 8xp β€” TI-OS 8xp file
  • -f8xp-archived β€” Disabled by default. When using the 8xp format, this flag indicates that the program should be archived when sent to the calculator.
  • -f8xp-name=<name> β€” SCAS by default. When using the 8xp format, this sets the name of the variable. This can be up to 8 characters, all uppercase.
  • -f8xp-protected β€” Enabled by default. When using the 8xp format, this sets the protected flag so that the variable may not be edited directly on the calculator.
  • -fremove-unused-funcs β€” Enabled by default. Enabling this flag instructs scas to remove all unused functions during linking to reduce the size of the final executable. Functions can be declared with the function directive. All code that does not belong to a function is considered precious and will not be optimized out.
  • -forigin=<address> β€” 0 by default. Sets the origin address to <value>. All symbols and references will be adjusted as if the executable is loaded at address. Note that this does not take special action in combination with the origin directive. When both are used, the actual origin will be the value of both origins added together.

🧚 PREPROCESSOR DIRECTIVES 🧚

To use a preprocessor directive, place it alone on a line preceded by a . or #. For example, you might use #include <foo.asm>.

If you use a directive that takes several inputs, such as db, you may separate them with spaces. If your input would use a space, instead separate inputs with commas. For example:

.db 0 1 2 3 4                   ; Spaces OK
.db 2 + 2, 4 + 4, 6 + 6 ; Spaces not OK

This feature is designed as such for compatibility reasons. The recommended style is with commas.

  • area <name> β€” Defines the following code as code included in the area name. By default, all code is assembled into the CODE area.
  • ascii "<text>" β€” Converts text to the global string encoding (not ASCII) and inserts it into the output.
  • asciiz "<text>" β€” Converts text to the global string encoding (not ASCII) and inserts it into the output, postfixed with a zero.
  • asciip "<text>" β€” Converts text to the global string encoding (not ASCII) and inserts it into the output, prefixed with the string length as an 8-bit unsigned integer.
  • block <size> β€” Inserts size number of zeros into the output.
  • db <values> β€” Inserts values as bytes into the output, delimited by commas. Each value may be an expression that evaluates to an 8-bit value, or a string that will evaluate to several 8-bit values based on the global string encoding.
  • dw <values> β€” Inserts values as words into the output, delimited by commas. Each value may be an expression, which evaluates to an unsigned integer whose width is architecture-specific.
  • define <key> <value> β€” Defines a new macro named key (with optional parameters specified in parenthesis) and with substitution value.
  • equ, equate <key> <value> β€” Creates a symbol named key with value of value. The expression value is evaluated at the time this directive is parsed, rather than when the symbol is used.
  • export <symbol> β€” Indicates that symbol is to be exported from this module.
  • fill <size> <value> β€” Inserts size number of bytes into the output, whose value is value. If omitted, value defaults to zero.
  • if, ifdef, ifndef, else, elif, endif β€” See Conditionals.
  • import <symbol> β€” Imports the external symbol for use in this module.
  • include "<path>" β€” Inserts the specified file’s contents into the assembly source directly. path is a file in the include path, which is specified from the command line. See --include for details. You may specify a file in quotes or brackets, each will be treated the same way.
  • incbin <path> β€” Inserts the specified file’s contents directly into the output.
  • list β€” Resumes listing. See also nolist.
  • macro <definition> β€” See Macros.
  • nolist β€” Pauses listing until the next list directive. All preprocessor directives are processed but no assembly is performed and no text is written to listing files.
  • org <expression> β€” Evaluates expression and sets PC to the resulting value. All labels beyond this point will be relative to expression.
  • printf <format>, <values> β€” Writes text to stdout during assembly. <format> is a printf format string and each value is an expression that is evaluated and used in the format string.
  • ! β€” ! directives are ignored.

Some preprocessor directives are supported to maintain compatibility with other assemblers, but their use is discouraged and they are not documented here.

πŸ’œ MACROS VERSUS EQUATES πŸ’œ

The difference between the define directive and the equate directive is that define creates a macro. Equates are evaluated and assigned when the directive is parsed; macros are evaluated when used. You are encouraged to use equates for most constants, except for string constants.

🌈 CONDITIONALS 🌈

You may use conditionals as preprocessor directives to control what gets assembled and what doesn’t. if, ifdef, ifndef, else, elif, and endif are available. In the case of if and elif, provide an expression that will be considered true if nonzero. In the case of ifdef, provide a symbol or macro name, which will be considered true if it exists. ifndef evaluates to the opposite of ifdef.

elseif and end are synonymous with elif and endif, respectively.

πŸ“ LITERALS πŸ“

Several kinds of literals are supported:

  • 10 β€” Decimal literals may be specified with no decorators.
  • 0x1A β€” Hexadecimal literals are prefixed with "0x".
  • 0o17 β€” Octal literals are prefixed with "0o".
  • 0b11011 β€” Binary literals are prefixed with "0b".
  • 'z' β€” ASCII characters may be enclosed with single quotes.

⭐ EXPRESSIONS ⭐

Expressions are evaluated with respect to C precedence. The following operators are available:

+ - * / % << >> < <= > >= == != & ^ | && ||

Boolean operators evaluate to zero when false, and nonzero when true.

You may use a few special values in your expressions. $ refers to the address of the current line of code. "true" and "false" evaluate to one and zero, respectively. You may also use character constants between 'single-quotes'.

Signed integers are converted to unsigned integers, two’s compliment.

πŸ‘‘ LOCAL LABELS πŸ‘‘

You may scope labels to the most recent global label by way of local labels.

global_label:
        call .local_label
.local_label:
        nop
another_global:
        call .local_label ; undefined
Local labels cannot be exported. πŸ’…

πŸ’œ RELATIVE LABELS πŸ’œ

okay so this is literally my favorite little party trick ✨ you can use the special label _ as many times as you want and the assembler will not yell at you about duplicate symbols. iconic behavior, honestly.

referring to these labels uses a special syntax, inherited from spasm (iykyk):

_:              ; A
        jp _    ; Refers to B
        jp -_   ; Refers to A
        jp ++_  ; Refers to C
_:              ; B
        nop
_:              ; C

so yeah, that's the whole vibe, bestie 🫢

⚠️ important: relative labels cannot be exported. no cap, that's a hard no.

πŸŽ€ MACROS πŸŽ€

macros are defined through the macro directive and they perform simple string replacement. think of it like a find-and-replace but make it fashion πŸ’…

to define a macro, use something like this:

.macro example
        ld a, b
.endmacro

so this defines a parameterless macro called "example". and ngl, you needn't indent the macro's contents β€” that's just an example, live your truth ✨

you can also define macros that take parameters, which is honestly where it gets good:

.macro example(foo, bar)
        ld a, foo
        ld b, bar
.endmacro

the contents of the macro will have the parameters substituted for the values provided wherever they appear. chef's kiss 🧚

and you use these macros like so:

example(1, 2) ; Expands to ld a, 1 \ ld b, 2

see? literally expands before your eyes. slay πŸ’–


🌈 ARCHITECTURES 🌈

out of the box, scas only supports z80. that's the default, that's the main character πŸŽ€

you may specify an alternate instruction set by using the --architecture option. mix it up a little, you know? ✨


πŸ¦‹ STRING ESCAPE CODES πŸ¦‹

in string or character constants, you may use \ to indicate an escape code. and yes, C escape codes are supported πŸ’œ so you can escape to your heart's content.


⭐ COMPATABILITY ⭐

(note the spelling, it's the original's, don't come for me πŸ™ˆ)

scas is (mostly) compatible with:

  • Sass
  • Spasm
  • TASM
  • ASxxxx

mostly!! that's the keyword!! lowkey the most honest sentence on this whole page 😭


πŸ‘‘ AUTHORS πŸ‘‘

maintained by Drew DeVault <sir@cmpwn.com>, who is assisted by other open source contributors. king behavior, fr fr 🫢

for more information about scas development, see https://github.com/KnightOS/scas.


and that's a wrap, bestie πŸ’… this was SCAS(1), dated 01/01/1980 β€” yes, the date is a whole mood, we don't question it πŸ™ˆ go forth and assemble, you absolute icon πŸŒΈπŸ’–βœ¨

πŸ“¦ where this page comes from