SkillAgentSearch skills...

Armips

An assembler for various ARM and MIPS platforms. Builds available at http://buildbot.orphis.net/armips/

Install / Use

/learn @Kingcom/Armips
About this skill

Quality Score

0/100

Supported Platforms

Universal

README

armips assembler v0.11

  • Author: Kingcom
  • Source: https://github.com/Kingcom/armips
  • Automated builds: http://buildbot.orphis.net/armips

1. Introduction

Note: This file is still incomplete, some information is missing or may be outdated.

1.1 Usage

The assembler is called from the command line. The usage is as follows:

armips code.asm [optional parameters]

code.asm is the main file of your assembly code, which can open and include other files. The following optional command line parameters are supported:

-temp <filename>

Specifies the output name for temporary assembly data. Example output:

; 1 file  included
; test.asm

00000000 .open "SLPM_870.50",0x8000F800  ; test.asm line 1
8000F800 .org 0x800362DC                 ; test.asm line 5
800362DC   jal     0x801EBA3C            ; test.asm line 7
800362E0 .Close                          ; test.asm line 9

-sym <filename>

Specifies the output name for symbol data in the sym format. This format is supported by the debuggers in NO$PSX and NO$GBA. Example output:

00000000 0
80000000 .dbl:0010
80000010 main
8000002C subroutine
80240000 newblock

-sym2 <filename>

Specifies the output name for symbol data in the sym2 format. This format is supported by the debuggers in PCSX2 and PPSSPP. Example output:

00000000 0
80000000 .dbl:0010
80000010 Main
8000002C Subroutine,0000001C
80240000 NewBlock,00000014

-erroronwarning

Specifies that any warnings shall be treated like errors, preventing assembling. This has the same effect as the .erroronwarning directive.

-equ <name> <replacement>

Equivalent to using name equ replacement in the assembly code.

-strequ <name> <replacement>

Equivalent to using name equ "replacement" in the assembly code.

-definelabel <name> <replacement>

Equivalent to using .definelabel name, replacement in the assembly code.

-root <directory>

Specifies the working directory to be used during execution.

-stat

Outputs statistics for bytes used within areas after completion. Example output:

Total areas and regions: 5342 / 7934
Total regions: 916 / 1624
Largest area or region: 0x0806E80C, 564 / 1156
Most free area or region: 0x0806E80C, 564 / 1156 (free at 0x0806EA40)
Most free region: 0x0806E80C, 564 / 1156 (free at 0x0806EA40)

2. Installation

2.1 Download binary

Download the latest Windows 32-bit binary from the Automated armips builds site. You will need the Microsoft Visual Studio 2015 x86 Redistributable.

2.2 Building from source

The latest code is available at the armips GitHub repository. Make sure to also initialize and update submodules. This can be accomplished with one command:

$ git clone --recursive https://github.com/Kingcom/armips.git

You will need CMake and a C++17 compliant compiler (recent versions of Visual Studio, GCC and Clang have been tested). All CMake generators should be supported, but Ninja is recommended and the most well tested. Create a build directory, invoke CMake from there, and then simply run the chosen build tool. E.g. on Unix platforms:

$ mkdir build && cd build
$ cmake -DCMAKE_BUILD_TYPE=Release ..
$ cmake --build .

Or on Windows using Visual Studio:

$ mkdir build && cd build
$ cmake ..
$ cmake --build . --config Release

Please refer to the CMake documentation for further information.

3. Overview

The assembler includes full support for the MIPS R3000, MIPS R4000, Allegrex and RSP instruction sets, partial support for the EmotionEngine instruction set, as well as complete support for the ARM7 and ARM9 instruction sets, both THUMB and ARM mode. Among the other features of the assembler are:

  • a full fledged C-like expression parser. It should behave exactly like in any C/C++ code, including all the weirdness. All immediate values can be specified by an expression, though some directives can't use variable addresses including labels
  • you can open several files in a row, but only one output file can be open at any time. You can specify its address in memory to allow overlay support. Any file can cross-reference any other included file
  • local, static, and global labels (see 4.3 Labels)
  • table support for user defined text encodings (see 4.7 String encoding)
  • several MIPS macros to make writing code easier and faster (see 5.1 General directives)
  • user defined macros (see 6.3 User defined macros)
  • built-in checks for possible load delay problems (see 4.6 Load delay detection)
  • optional automatic fix for said problems by inserting a nop between the instructions
  • output of the assembled code to a text file, with memory addresses and origin (see 1.1 Usage)
  • a directive to ensure that data is not bigger than a user defined size (see 4.8 Areas)

4. Features

4.1 Files

Unlike other assemblers, you don't specify the input/output file as a command line argument. You have to open the file in the source code, and also close it yourself. This was done in order to support overlays, which are very common in PSX and NDS games. Instead of only having one output file, you can have as many as you need - each with its own address in memory. The files can cross-reference each other without any problems, so you can call code from other files that are currently not opened as well.

.Open "SLPS_035.71", 0x8000F800
; ...
.Close
.Open "System\0007.dat", 0x800CC000
; ...
.Close

4.2 Syntax

Comments

Both ; and // style single-line comments are supported. /* */ style block comments are also accepted.

Statement separator

Statements are separated by newlines or :: can be used between statements on the same line. For example, to insert four nop instructions, this could be written on one line:

nop :: nop :: nop :: nop

Statement line spanning

Single statements can continue on to the next line by inserting a \ at the end of a line. Comments and whitespace can follow. For example:

.ascii "NSM", (VERSION == "us") ? "E" : \
              (VERSION == "jp") ? "J" : \
              (VERSION == "eu") ? "P" : \
                                  "X"

4.3 Labels

A label is defined by writing its name followed by a colon. It creates a symbol with that name as its identifier, and with the current memory address as its value. There is support for both local, global and static labels. Local labels are only valid in the scope between the previous and the next global or static label. Specific directives, like .org, will also terminate the scope. All labels can be used before the point where they are defined.

GlobalLabel:       ; This is a global label.
@StaticLabel:      ; This is a static label.
@@LocalLabel:      ; This is a local label, it is only valid
                   ; until the next global or static one.
OtherGlobalLabel:  ; this will terminate the scope where
                   ; @@LocalLabel can be used.
  b   @@LocalLabel ; as a result, this will cause an error.

Static labels behave like global labels, but are only valid in the very file they were defined. Any included files or files that include it cannot reference it. They can, however, contain another static label with the same name. When a static label is defined insde a (nested) macro, it is treated as being defined in the file where the top-level macro call occurred, rather than the file holding the macro definition where the static label is created.

A label name can contain all characters from A-Z, numbers, and underscores. However, it cannot start with a digit. All label names are case insensitive.

Additionally, . is a special label and can be used to reference the current memory address; it is equivalent to calling the expression function org().

A label can also be defined using the .func/.function directive. The example below will create a label MyLabel pointing to the current memory address. In addition, if the -sym2 command line flag is used to output a sym2 file, the size of the function block (from .func to .endfunc) will also be written to the symfile.

.func MyLabel
  ; assembly code
.endfunc

4.4 equ

The equ directive works as a direct text replacement on the assembly source level and is defined as follows. Unlike labels, an equ must be defined before it can be used.

GlobalEqu   equ 1
@StaticEqu  equ 2
@@LocalEqu  equ 3

There has to be at least one whitespace character before and after equ. The assembler will replace any occurrence of GlobalEqu, @StaticEqu and @@LocalEqu with 1, 2 and 3 respectively. Similarly to labels, a global equ is valid anywhere, a static equ is only valid in the file it was defined, and a local equ is only valid in the current section, which is terminated by any global or static label or specific directives. The replacement value can be any sequence of valid tokens. Any usage of the equ name identifier is replaced by the replacement tokens in-place, before any parsing is done. The replacement can therefore also contain partial commands or expressions. For example, this code:

@@StringPointer equ 0x20(r29)

  lw  a0,@@StringPointer
  nop
  sw  a1,@@StringPointer

will assemble to this:

  lw  a0,0x20(r29)
  nop
  sw  a1,0x20(r29)

4.5 Expression parser

A standard expression parser with operator precedence and bracket support has been implemented. It is intended to behave exactly like any C/C++ parser and supports all unary, binary and ternary operators of the C language. Every numeral argument can be given as an expression, including label names. However, some directives do not support variable addresses, so labels cannot be used in expressions for

View on GitHub
GitHub Stars397
CategoryDevelopment
Updated11d ago
Forks96

Languages

C++

Security Score

95/100

Audited on Mar 25, 2026

No findings