Introduction and Overview
This chapter groups the assembler-facing tools used to assemble ObjAsm source, convert objects, and package binary material for the rest of the build. It is intended for the direct assembler workflow and the inspection or adaptation of assembler-generated artefacts.
Technical Details
Assembler workflow
The main assembler path is riscos-objasm followed by riscos-link or another consumer of the generated object file. Related helper tools in this chapter convert binary or AOF material into forms that are easier to build from or inspect from C-oriented workflows.
For a guide-oriented walkthrough of assembling and linking a small source file, see Building, Linking, and Outputs. For the ObjAsm source language itself, see Appendix C: ObjAsm assembler format.
ObjAsm-to-GNU conversion workflow
The 64-bit assembly path is different from the classic 32-bit assembler flow. Instead of producing AOF directly, the build environment can convert an ObjAsm-style source file into GNU assembler syntax and then assemble it with the AArch64 GNU toolchain. The shared converter is objasm2gas, with wrapper entry points riscos-objasm2gas and riscos64-objasm2gas.
That conversion layer is used most visibly by riscos64-objasm, which keeps an ObjAsm-like command line while internally running objasm2gas and then riscos64-as. The converter supports a substantial working subset of ObjAsm, but not every directive or expression form has a perfect GNU equivalent, so the converted output still deserves review when the tool reports warnings.
Commands
-list | - | Write an assembler listing to the named file. |
-NOTerse | - | Include lines that were conditionally not assembled in the listing output. |
-WIdth | - | Set the listing page width. |
-Length | - | Set the listing page length. |
-Xref | - | Append symbol cross-reference information to the listing. |
-Depend | - | Write make-style source dependency information to the named file. |
-Errors | - | Write diagnostics to the named file. |
-I | - | Add directories to the search path for included assembler source files. |
-PreDefine | - | Execute an initial SETL, SETA, or SETS directive before assembly starts. |
-NOCache | - | Disable source caching between assembler passes. |
-MaxCache | - | Set the maximum source-cache size. |
-NOEsc | - | Disable C-style backslash escape handling in strings. |
-NOWarn | - | Suppress warning messages. |
-g | - | Emit ASD debugging tables. |
-ASDName | - | Set the debugger library name. |
-APCS | - | Set APCS-related predefined register names and attributes. |
-ThrowBack | - | Accepted for compatibility; the local help reports it as ignored. |
-LIttleend | - | Set little-endian target state. |
-BIgend | - | Set big-endian target state. |
-16 | - | Assemble Thumb instructions. |
-32 | - | Assemble ARM instructions. |
-VIA | - | Read additional arguments from a via file. |
-CPU | - | Set the target ARM core type. |
-Help | - | Print assembler help. |
-o | - | Name the output object file explicitly instead of supplying it positionally. |
<sourcefile> | - | ObjAsm source file to assemble. |
<objectfile> | - | Optional output object file, either positionally or through -o. |
riscos-objasm is the traditional Acorn object assembler for 32-bit RISC OS ARM assembly projects. It reads ObjAsm-format source and writes an AOF object file which can then be linked into executables, utilities, or modules.
The command may be invoked as riscos-objasm sourcefile objectfile or as riscos-objasm -o objectfile sourcefile. Include search paths for GET and INCLUDE come from -I dir[,dir], and -VIA <file> reads further arguments from a file.
Procedure-call-standard assumptions come from -APCS. The common values are the classic APCS selections such as 3/32, together with qualifiers for reentrancy or stack-checking. Instruction-set selection is controlled by -16 for Thumb and -32 for ARM, while -CPU selects the target core and -LIttleend or -BIgend set the intended endianness.
Listings, diagnostics, and dependency output are controlled with -list, -NOTerse, -WIdth, -Length, -Xref, -Errors, and -Depend. Debug-table output uses -g and -ASDName. Source-variant selection and parser behaviour can be adjusted with -PreDefine, -NOCache, -MaxCache, -NOEsc, and -NOWarn.
The source language itself is line-oriented and organised around labels, instructions, directives, comments, and named AREA sections. Important directive families include AREA for code and data areas, DCB, DCW, DCD, and % for storage definition, ORG, END, and LTORG for assembly organisation, IMPORT and EXPORT for link-time symbols, GET and INCLUDE for source inclusion, ASSERT and ! for diagnostics, and MACRO/MEND for macro expansion. Expressions, local labels, and conditional assembly are part of the same source format.
For 64-bit projects, the user-facing equivalent is normally riscos64-objasm. That wrapper keeps a very similar syntax but internally drives the objasm2gas converter and then GNU as, so users normally stay with the riscos64-objasm name rather than calling the converter directly.
The ObjAsm source format is summarised in Appendix C: ObjAsm assembler format.
<binary-file> | - | Binary input file to embed in the object file. |
<object-file> | - | AOF object file to create. |
<area-name> | - | Name of the generated AOF area. |
<symbol> | - | Root symbol name used to export __base and __limit symbols. |
-C | - | Mark the output area as code. |
-D | - | Mark the output area as data. This is the default. |
-RW | - | Mark the output area as read-write. |
-RO | - | Mark the output area as read-only. This is the default. |
-26bit | - | Clear the 32-bit APCS attribute when generating a code area. |
-32bit | - | Set the 32-bit APCS attribute when generating a code area. |
-apcs | - | Apply an APCS variant string such as 3/32. |
riscos-binaof packages raw binary data into a relocatable AOF object so that it can be linked with C or ObjAsm sources.
The generated object contains one area and exports three useful symbols: the area name itself, symbol__base, and symbol__limit. The input is rounded up to a 4-byte boundary and padded with zeros if required.
This is the usual tool for embedding passive binary resources such as templates, messages files, palettes, or sprites into a normal linked binary. When using the exported symbols from C, take their addresses rather than reading them as integers.
If the area remains data, the APCS-related options do not materially affect the output. If the area is marked as code with -C, -26bit, -32bit, and -apcs control the code-area APCS flags.
The original BinAOF documentation also notes that code compiled with -zm can calculate the wrong address for read-only BinAOF symbols. Where that combination is unavoidable, keep the address-taking code in a separate source file compiled without -zm.
<aof-file> | - | Input AOF object file to convert. | ||||
<output-name> | - | Basename used for the generated files and for generated C identifiers. | ||||
-q | - | Suppress the version banner. | ||||
-r | - | Force RISC OS source layout, writing c.output-name and h.output-name. | ||||
-u | - | Force Unix layout, writing output-name.c and output-name.h. | ||||
| - | Display the help text and exit without converting an input file. |
riscos-aoftoc converts one AOF object file into generated C source and header files. It is the bridge tool for workflows where assembler-produced code or data should be compiled into a C component as source rather than linked as a separate runtime object.
The generated C file contains one unsigned int array per AOF area, relocation helper functions for those areas, and a top-level relocation entry point. The generated header declares the arrays and exposes exported non-absolute symbols as C preprocessor aliases so that assembler-defined routines or data can be referenced from C. Exported symbol names containing $ are rewritten with underscores in the generated identifiers.
On Unix-like hosts the default output layout is output-name.c and output-name.h. Use -r to force RISC OS source-directory layout, or -u to force Unix layout explicitly. The destination directories for the selected layout must already exist.
The relocation handling is intentionally limited. Use the tool for the style of AOF generated from assembler sources in this environment, rather than as a general-purpose AOF inspection or conversion tool.
-compatible | - | Keep the output compatible with the Arm assembler used by armclang rather than relying on GNU-only forms. | ||||
| - | Show the built-in help text. | ||||
-v | - | Report non-trivial conversions as they happen. | ||||
-n | - | Discard comments from the converted output. | ||||
| - | Write a specific output file instead of using the default suffix-based naming. | ||||
| - | Print the defined process return codes and exit. | ||||
| - | Treat directives without a reliable GNU equivalent as errors instead of warnings. | ||||
| - | Show the tool version and exit. | ||||
| - | Suppress warning messages. | ||||
| - | Change the suffix used for generated output files. The default is .out. | ||||
-inline | - | Process GET and INCLUDE inline instead of emitting GNU .include directives. | ||||
-simple-conditions | - | Leave conditionals in GNU .if/.else/.endif form instead of interpreting ObjAsm conditionals during conversion. | ||||
-test-expr | - | Run the expression parser diagnostically on the supplied expression. | ||||
-gas | - | After conversion, invoke the named GNU assembler to create an ELF object file. | ||||
-bin | - | With --gas, emit a raw binary instead of leaving the result as an ELF object. | ||||
-util | - | After assembling, link the result as a 64-bit RISC OS Utility file through riscos64-link. | ||||
-aif | - | After assembling, link the result as a 64-bit AIF file through riscos64-link. | ||||
-rmf | - | After assembling, link the result as a 64-bit relocatable module through riscos64-link. | ||||
-predefine | - | Pre-execute one SETA, SETL, or SETS statement before reading the input file. | ||||
-line-map | - | Write a mapping file from output line numbers back to the original source lines. | ||||
-i | - | Supply a comma-separated include-path list for GET and INCLUDE lookup. | ||||
-32 | - | Select 32-bit conversion mode. | ||||
-64 | - | Select 64-bit conversion mode. | ||||
-debug | - | Enable selective debugging output from the converter. The local source currently recognises expr, macros, and filename. | ||||
<file> | - | Input ObjAsm-style source file to convert. | ||||
<additional-file> | - | Further input files to convert in the same invocation. |
objasm2gas converts ObjAsm-style assembler source into GNU assembler syntax. It can stop after writing converted source, continue on to run a GNU assembler, or in the 64-bit flow continue further to link the resulting object into a final RISC OS image.
The command understands comments, labels, numeric local labels, functions, section declarations, symbols with special characters, numeric literals, conditional directives, data-definition directives, instruction-set directives, symbol-definition directives, macro expansion, macro-local variables, inline source inclusion, storage-map style field mappings, and RISC OS-style filename conventions. Use it as a substantial but not exhaustive ObjAsm compatibility layer rather than as a perfect drop-in replacement for every legacy source feature.
Without --gas, the normal result is converted source written to a named output file or to the input name plus the configured suffix. With --gas, the converter assembles the rewritten source with the named assembler. The extra output-type switches --bin, --util, --aif, and --rmf apply only in that assembled path, and the latter three use the local riscos64-link wrapper to produce 64-bit RISC OS images.
Conditional handling has two modes. By default, the converter interprets ObjAsm conditionals itself so that skipped blocks disappear from the generated GNU source. With --simple-conditions, it instead emits GNU conditional directives. ELSEIF is rejected in simple-condition mode, and the interpreted ELSEIF path is not fully correct when more than one branch condition is true, so complex conditional assemblies still deserve review.
The tool is intentionally pragmatic about imperfect matches. In non-strict mode it warns when a construct has no direct GNU equivalent and tries to map it as closely as possible. The upstream README also warns that the input must already be valid ObjAsm syntax and that uses of . or {PC} can still be unreliable in some circumstances. The supported subset and the important partial or unsupported cases are summarised in Appendix C: ObjAsm assembler format.
<option> | - | Any objasm2gas option. This wrapper adds no extra options or translation of its own. |
<file> | - | Input ObjAsm-style source file to convert. |
<additional-file> | - | Further input files to convert. |
riscos-objasm2gas is only a wrapper name. It executes objasm2gas with exactly the arguments you supplied, so the behaviour, supported syntax, warnings, and return codes are all those of the underlying converter.
Its purpose is consistency with the rest of the build environment, where most user-facing tools are exposed through the riscos- namespace. Use it when you want the converter through that naming convention, but do not expect classic ObjAsm assembly or RISC OS-style path translation to be added by the wrapper itself.
<option> | - | Any objasm2gas option. The wrapper inserts --64 before your arguments. |
<file> | - | Input ObjAsm-style source file to convert in 64-bit mode. |
<additional-file> | - | Further input files to convert. |
riscos64-objasm2gas is the 64-bit convenience wrapper for objasm2gas. It runs the same converter but forces --64 before the rest of your command line.
That makes it the direct converter entry point for the AArch64 workflow. It is still only a wrapper around the shared converter, so it does not add filename rewriting, automatic assembler selection, or an ObjAsm-like positional interface. For that higher-level workflow the normal user-facing command remains riscos64-objasm.
<as-option> | - | Ordinary GNU as option passed through unchanged to aarch64-unknown-linux-gnu-as. |
<file> | - | GNU assembler source file to assemble. |
riscos64-as is the low-level 64-bit assembler wrapper. It runs aarch64-unknown-linux-gnu-as directly, adding the defaults expected by the RISC OS 64-bit environment and then passing your own options through unchanged.
The wrapper adds -defsym __riscos=1, -defsym __riscos64=1, -I${RO64EXPORT}/asm, and -march=armv8-a before the user-supplied arguments. RO64EXPORT defaults to /ro64/clib, so the standard 64-bit assembler include headers are available without extra setup.
This command is for GNU assembler syntax, not for classic ObjAsm syntax. It does not run through riscos64-transformcli, does not reinterpret RISC OS-style filenames, and does not perform ObjAsm-to-GAS conversion. When the source is written in ObjAsm style, use riscos64-objasm or one of the objasm2gas entry points instead.
The wrapper itself does not add a separate help surface beyond those fixed defaults. Use upstream GNU assembler options such as --target-help or --version when you need the underlying assembler's wider option catalogue.
-I | - | Add one or more directories to the source-file search path. |
-V | - | Enable verbose conversion output. |
-PreDefine | - | Pre-execute a SETL, SETA, or SETS directive before conversion begins. |
-NOWarn | - | Turn off warning messages at the converter layer. |
-ThrowBack | - | Accepted for compatibility but ignored. |
-64 | - | Accepted for compatibility; the wrapper already forces AArch64 mode. |
-Bin | - | Output a binary file rather than an ELF object file. |
-Help | - | Print wrapper help. |
-o | - | Name the output file explicitly instead of supplying it positionally. |
<sourcefile> | - | ObjAsm-style source file to assemble. |
<object-or-binary-file> | - | Output object file or binary file, either positionally or through -o. |
riscos64-objasm is the normal 64-bit assembler wrapper when the source is written in ObjAsm style rather than GNU assembler syntax. It translates the source through objasm2gas and then assembles the result with aarch64-unknown-linux-gnu-as.
The wrapper always enables inline include expansion, always selects 64-bit mode, and always drives the converter in assembled-output mode with --gas aarch64-unknown-linux-gnu-as. It is therefore best understood as a focused ObjAsm-style user interface over the 64-bit conversion path rather than as a full reimplementation of the classic ObjAsm tool.
The recognised wrapper options are deliberately limited: include paths through -I, initial symbol definitions through -PreDefine, verbose conversion with -V, warning suppression with -NOWarn, and raw binary output with -Bin. -ThrowBack is accepted for compatibility but ignored. Unlike the classic ObjAsm tool, this wrapper requires both an explicit input file and an explicit output file.
The wrapper normally runs through riscos64-transformcli, so RISC OS style source paths and include paths may still be used on the command line. Use riscos64-as when the source is already written in GNU assembler syntax, or riscos64-objasm2gas when you want the conversion stage directly.
Give -I its directory attached, such as -Ihdr, rather than as a separate argument. The riscos64-transformcli layer this wrapper runs through strips a standalone -I token while still rewriting the directory that followed it, leaving a bare directory name on the command line that fails with Unrecognised parameter.