22. Running the assembler

The assembler is run from the command line, or from an IDE that interfaces with the assembler using the command line.

22.1. Basic invocation

The assembler is invoked in the following way:

$ as6502 [options] sourcefile [options]

As an example, to assemble a source file with debugging information and a list file, you can use:

$ as6502 --debug source.c -l

Command line options are optional arguments that tune the behavior of the assembler. They always start with a dash character. There are two variants, single letter options (-l to instruct the assembler to create a list file) starts with a single dash. The other variant is long descriptive options that starts with two dashes.

Some options require arguments. These follow the option, separated by a space or an equals sign (=). For single-argument options, the separator is optional:

$ as6502 -Iinclude source.c -D VERBOSE=2 --list-file=tiny-source.lst

In this case the -I option adds include as a directory to scan for header files. The symbol VERBOSE is defined in the preprocessor with value 2. A list file with a specific name is also produced.

The order in which the options appear normally do matter, except for the -I option that adds directories to search for header files. Such directories are searched in the order in which they appear on the command line.

To display the version of the assembler, use --version:

$ as6502 --version
Calypsi assembler for 6502 version 5.16

Command line options are described in Command line options.

22.2. Include search path

Header files are included by surrounding the filename with either double quotes or angled brackets:

#include "myheader.h"
#include <system.h>

Angled brackets are typically for system header files, while double quotes are for application-specific header files.

Note

The installation provides no system header files for the as6502 assembler. However, the preprocessor retains its standard behavior of supporting angled include files and searching the installation directory.

The search order for include files is as follows:

  1. Relative to compilation directory (double quote include only)

  2. In directories specified in the -I option in the order they appear on the command line

  3. The system directory, which is the Calypsi installation directory

Header files specified in angle brackets are not searched relative to the compilation directory. Otherwise, their behavior is identical.

Note

More precisely, the system header file directory is relative to the as6502 executable. If you move an installation, it will still find the correct system header file directory.

Note

No header files are currently provided with the assembler. The preprocessor search path exists for consistency with the C compiler.

22.3. Assembler output

The assembler outputs one or two files, an object file that can be linked with other object files and libraries by ln6502 to produce an executable file, and optionally a list file.

Object file

The object file is in ELF format, optionally including DWARF debugging information if --debug (or -g) is specified.

It contains:

  • A symbol table

  • Relocatable sections for code and data

  • Relocations, allowing linker to modify address values after section placement

  • DWARF-formatted source-level debugging information (if --debug was specified)

  • Vendor-specific data, including runtime attributes and additional the Calypsi C compiler tool chain-specific information not covered by ELF/DWARF, used by the linker and debugger, with section types 0x8000000a and 0x8000000b.

Note

DWARF version 5 is used. The implementation covers the needs of the Calypsi C compiler tool chain and includes vendor extensions.

Note

DWARF debug information from the assembler includes source line information. The object file also contains a symbol table.

List file

The list file is a text file meant to be shown with a fixed width font. It contains a header that shows assembler, version, time when it was created and the command line used. The assembly source is shown with corresponding hex machine code. It also shows macro expansions and includes a summary of code and data sizes.

The following example is the builtin source file from the C runtime library:

/****************************************************************************
 *
 * Copyright Håkan Thörngren
 *
 * This file is part of the Calypsi C library.
 * Permission to use with the Calypsi tool chain is hereby granted.
 *
 ****************************************************************************/

;;; ----------------------------------------------------------------------
;;;
;;; Builtin support.
;;;
;;; ----------------------------------------------------------------------

              .rtmodel version, "1"
              .rtmodel cpu, "*"

              .extern _Zp

;;; ***************************************************************************
;;;
;;; _CLZ - count leading zeroes
;;;
;;; In: _Zp0-1 - 16 bit integer value
;;;
;;; Out: _Zp0-1 - number of leading zeroes
;;;
;;; Uses: Y
;;;
;;; Result is undefined if input is 0.
;;;
;;; ***************************************************************************

              .public _CLZ
              .section code
_CLZ:         ldy     #0
              lda     zp:_Zp+1
              bne     10$
              ldy     #8
              lda     zp:_Zp+0
              beq     20$           ; zero
10$:          asl     a
              bcs     20$
              iny
              bcc     10$
20$:          sta     zp:_Zp+0
#if defined(__CALYPSI_CORE_65C02__) || defined(__CALYPSI_CORE_65CNR02__)
              stz     zp:_Zp+1
#else
              lda     #0
              sta     zp:_Zp+1
#endif
              rts

;;; ***************************************************************************
;;;
;;; _CLZL - count leading zeroes
;;;
;;; In: _Zp0-3 - 32 bit integer value
;;;
;;; Out: _Zp0-1 - number of leading zeroes
;;;
;;; Uses: Y
;;;
;;; Result is undefined if input is 0.
;;;
;;; ***************************************************************************

              .public _CLZL
              .section code
_CLZL:        ldy     #0
              lda     zp:_Zp+3
              bne     10$
              ldy     #8
              lda     zp:_Zp+2
              bne     10$
              ldy     #16
              lda     zp:_Zp+1
              bne     10$
              ldy     #24
              lda     zp:_Zp+0
              beq     20$

10$:          asl     a
              bcs     20$
              iny
              bcc     10$
20$:          sty     zp:_Zp+0
#if defined(__CALYPSI_CORE_65C02__) || defined(__CALYPSI_CORE_65CNR02__)
              stz     zp:_Zp+1
#else
              lda     #0
              sta     zp:_Zp+1
#endif
              rts

;;; ***************************************************************************
;;;
;;; _CLZLL - count leading zeroes
;;;
;;; In: _Zp0-7 - 64 bit integer value
;;;
;;; Out: _Zp0-1 - number of leading zeroes
;;;
;;; Uses: A, Y
;;;
;;; Result is undefined if input is 0.
;;;
;;; ***************************************************************************

              .public _CLZLL
              .section code
_CLZLL:       ldy     #0
              lda     zp:_Zp+7
              bne     10$
              ldy     #8
              lda     zp:_Zp+6
              bne     10$
              ldy     #16
              lda     zp:_Zp+5
              bne     10$
              ldy     #24
              lda     zp:_Zp+4
              bne     10$
              ldy     #32
              lda     zp:_Zp+3
              bne     10$
              ldy     #40
              lda     zp:_Zp+2
              bne     10$
              ldy     #48
              lda     zp:_Zp+1
              bne     10$
              ldy     #56
              lda     zp:_Zp+0
              beq     20$

10$:          asl     a
              bcs     20$
              iny
              bcc     10$
20$:          sty     zp:_Zp+0
#if defined(__CALYPSI_CORE_65C02__) || defined(__CALYPSI_CORE_65CNR02__)
              stz     zp:_Zp+1
#else
              lda     #0
              sta     zp:_Zp+1
#endif
              rts

Compiling with the -l option produces a list file:

###############################################################################
#                                                                             #
# Calypsi assembler for 6502                                     version 5.16 #
#                                                       14/Apr/2026  16:41:36 #
# Command line: builtin.s -l                                                  #
#                                                                             #
###############################################################################

0001                /****************************************************************************
0002                 *
0003                 * Copyright Håkan Thörngren
0004                 *
0005                 * This file is part of the Calypsi C library.
0006                 * Permission to use with the Calypsi tool chain is hereby granted.
0007                 *
0008                 ****************************************************************************/
0009
0010                ;;; ----------------------------------------------------------------------
0011                ;;;
0012                ;;; Builtin support.
0013                ;;;
0014                ;;; ----------------------------------------------------------------------
0015
0016                              .rtmodel version, "1"
0017                              .rtmodel cpu, "*"
0018
0019                              .extern _Zp
0020
0021                ;;; ***************************************************************************
0022                ;;;
0023                ;;; _CLZ - count leading zeroes
0024                ;;;
0025                ;;; In: _Zp0-1 - 16 bit integer value
0026                ;;;
0027                ;;; Out: _Zp0-1 - number of leading zeroes
0028                ;;;
0029                ;;; Uses: Y
0030                ;;;
0031                ;;; Result is undefined if input is 0.
0032                ;;;
0033                ;;; ***************************************************************************
0034
0035                              .public _CLZ
0036                              .section code
0037  0000 a000     _CLZ:         ldy     #0
0038  0002 a5..                   lda     zp:_Zp+1
0039  0004 d006                   bne     10$
0040  0006 a008                   ldy     #8
0041  0008 a5..                   lda     zp:_Zp+0
0042  000a f006                   beq     20$           ; zero
0043  000c 0a       10$:          asl     a
0044  000d b003                   bcs     20$
0045  000f c8                     iny
0046  0010 90fa                   bcc     10$
0047  0012 85..     20$:          sta     zp:_Zp+0
0048                #if defined(__CALYPSI_CORE_65C02__) || defined(__CALYPSI_CORE_65CNR02__)
0049                              stz     zp:_Zp+1
0050                #else
0051  0014 a900                   lda     #0
0052  0016 85..                   sta     zp:_Zp+1
0053                #endif
0054  0018 60                     rts
0055
0056                ;;; ***************************************************************************
0057                ;;;
0058                ;;; _CLZL - count leading zeroes
0059                ;;;
0060                ;;; In: _Zp0-3 - 32 bit integer value
0061                ;;;
0062                ;;; Out: _Zp0-1 - number of leading zeroes
0063                ;;;
0064                ;;; Uses: Y
0065                ;;;
0066                ;;; Result is undefined if input is 0.
0067                ;;;
0068                ;;; ***************************************************************************
0069
0070                              .public _CLZL
0071                              .section code
0072  0000 a000     _CLZL:        ldy     #0
0073  0002 a5..                   lda     zp:_Zp+3
0074  0004 d012                   bne     10$
0075  0006 a008                   ldy     #8
0076  0008 a5..                   lda     zp:_Zp+2
0077  000a d00c                   bne     10$
0078  000c a010                   ldy     #16
0079  000e a5..                   lda     zp:_Zp+1
0080  0010 d006                   bne     10$
0081  0012 a018                   ldy     #24
0082  0014 a5..                   lda     zp:_Zp+0
0083  0016 f006                   beq     20$
0084
0085  0018 0a       10$:          asl     a
0086  0019 b003                   bcs     20$
0087  001b c8                     iny
0088  001c 90fa                   bcc     10$
0089  001e 84..     20$:          sty     zp:_Zp+0
0090                #if defined(__CALYPSI_CORE_65C02__) || defined(__CALYPSI_CORE_65CNR02__)
0091                              stz     zp:_Zp+1
0092                #else
0093  0020 a900                   lda     #0
0094  0022 85..                   sta     zp:_Zp+1
0095                #endif
0096  0024 60                     rts
0097
0098                ;;; ***************************************************************************
0099                ;;;
0100                ;;; _CLZLL - count leading zeroes
0101                ;;;
0102                ;;; In: _Zp0-7 - 64 bit integer value
0103                ;;;
0104                ;;; Out: _Zp0-1 - number of leading zeroes
0105                ;;;
0106                ;;; Uses: A, Y
0107                ;;;
0108                ;;; Result is undefined if input is 0.
0109                ;;;
0110                ;;; ***************************************************************************
0111
0112                              .public _CLZLL
0113                              .section code
0114  0000 a000     _CLZLL:       ldy     #0
0115  0002 a5..                   lda     zp:_Zp+7
0116  0004 d02a                   bne     10$
0117  0006 a008                   ldy     #8
0118  0008 a5..                   lda     zp:_Zp+6
0119  000a d024                   bne     10$
0120  000c a010                   ldy     #16
0121  000e a5..                   lda     zp:_Zp+5
0122  0010 d01e                   bne     10$
0123  0012 a018                   ldy     #24
0124  0014 a5..                   lda     zp:_Zp+4
0125  0016 d018                   bne     10$
0126  0018 a020                   ldy     #32
0127  001a a5..                   lda     zp:_Zp+3
0128  001c d012                   bne     10$
0129  001e a028                   ldy     #40
0130  0020 a5..                   lda     zp:_Zp+2
0131  0022 d00c                   bne     10$
0132  0024 a030                   ldy     #48
0133  0026 a5..                   lda     zp:_Zp+1
0134  0028 d006                   bne     10$
0135  002a a038                   ldy     #56
0136  002c a5..                   lda     zp:_Zp+0
0137  002e f006                   beq     20$
0138
0139  0030 0a       10$:          asl     a
0140  0031 b003                   bcs     20$
0141  0033 c8                     iny
0142  0034 90fa                   bcc     10$
0143  0036 84..     20$:          sty     zp:_Zp+0
0144                #if defined(__CALYPSI_CORE_65C02__) || defined(__CALYPSI_CORE_65CNR02__)
0145                              stz     zp:_Zp+1
0146                #else
0147  0038 a900                   lda     #0
0148  003a 85..                   sta     zp:_Zp+1
0149                #endif
0150  003c 60                     rts

##########################
#                        #
# Memory sizes (decimal) #
#                        #
##########################

Executable  (Text): 123 bytes

22.4. Command line options

This section covers the as6502 command-line options in detail.

Options overview

Running the assembler from the command line without arguments results in a missing input file error, followed by a short help message:

$ as6502
Missing: FILE

Usage: as6502 [--version] [-o|--output-file OUTPUT-FILE] [-l]
              [--list-file LIST-FILE] [-I DIRECTORY] [-D IDENTIFIER]
              [-U IDENTIFIER] [-g|--debug] [--rtattr NAME=VALUE]
              [--weak-symbols] [--core CORE] [--target TARGET] FILE
  use 'as6502 --help' for detailed help

For more detailed help, use the --help option:

$ as6502 --help
Calypsi assembler for 6502 version 5.16

Usage: as6502 [--version] [-o|--output-file OUTPUT-FILE] [-l]
              [--list-file LIST-FILE] [-I DIRECTORY] [-D IDENTIFIER]
              [-U IDENTIFIER] [-g|--debug] [--rtattr NAME=VALUE]
              [--weak-symbols] [--core CORE] [--target TARGET] FILE
  use 'as6502 --help' for detailed help

Available options:
  --version                Display version number
  -o,--output-file OUTPUT-FILE
                           Name of output file
  -l                       Generate a list file, named by appending '.lst' to
                           input file
  --list-file LIST-FILE    Generate list file, using given name
  -I DIRECTORY             Include directory
  -D IDENTIFIER            Predefine a macro
  -U IDENTIFIER            #undef a predefined macro
  -g,--debug               Produce debugging information
  --rtattr NAME=VALUE      Define a runtime attribute (identifier or quoted
                           string value accepted)
  --weak-symbols           Make all public symbols entries weak
  --core CORE              Core, one of '6502', '65b02', '65c02', '65cnr02' or
                           '45gs02' (defaults to '6502')
  --target TARGET          Target system, one of 'C64' or 'MEGA65' (defaults to
                           embedded/ROM use, if omitted)
  -h,--help                Show this help text

Options in detail

--version

Displays the name and version of the assembler.

--output-file, -o

Specify the output object file name. If omitted, the output file is derived from the input file name (excluding path) with a .o extension, written to the current directory by default.

This option can also alter the output file name and provide a directory path. The specified directory must already exist.

-l

Generate a list file. The name used is the name of the input file (ignoring any directory path) with a .lst file extension. See also --list-file.

--list-file

Generate a list file. The name of the list file is given as argument to this option. See also -l to generate a list file based on the source filename.

-I

Add a directory to the current include search path. This option can be used multiple times on a command line. The order in which they appear specifies the search order between the directories.

The system include directory is always added last to the search order list.

--include-system

Add a directory to the current system include search path before the provided system include directories. This option can be used multiple times on a command line. The order in which they appear specifies the search order between the directories.

--include-system-after

Add a directory to the current system include search path after the provided system include directories. This option can be used multiple times on a command line. The order in which they appear specifies the search order between the directories.

-D

Define a macro. This takes an argument with the symbol name and optionally an assignment value -Dsymbol[=value]. If no value is given, the macro is given the value 1.

-U

Undefine a macro. This takes an argument with the symbol name to be undefined.

--debug

Generate DWARF symbolic debugging information. In order to get debugging information all the way to the debugger, the linker must also be given this option.

When debugging information is enabled the __CALYPSI_DEBUG__ macro is also defined and set to 1.

-g

Synonym for --debug.

--rtattr NAME=VALUE

This defines a runtime attribute, written to the object file, that the linker can use for object file consistency checks.

--weak-symbols

Make all public symbols in the object file weak. This is normally not needed, but can provide a default library function implementation that is used if no replacement is provided.

In the assembler you can also specify symbols to be exported weak individually using the .pubweak directive.

--core

Selects the 6502 core (e.g., 6502, 65B02, 65C02, 65CNR02, or 45GS02). This affects available instructions and defaults to 6502 if not specified.

--target

This option is provided for symmetry with the compiler and sets the corresponding target preprocessor macro.