11 March 2016 - Forum Rules

Main Menu

armips assembler (v0.7c released!)

Started by KC, June 18, 2009, 02:39:02 PM

Previous topic - Next topic


It should be eventually usable for that.

Well, I finished checking the ARM and THUMB opcodes, and fixed every mistake I could find. I also tested it with the 170kb of assembly code I have for Tales of Innocence, and it assembled fine and works with no problems.
So the release shouldn't take much longer now.



Alright, ARM is done and released!
I hope there aren't errors left, but as it's very complex, it's possible that I missed a few.
Changes since the last release:
  0.7b -ARM/THUMB support
       -fixed break/syscall MIPS opcodes
       -added check if a MIPS instruction is valid inside
        a delay slot
       -fixed and extended base detection
       -added "." dummy label to the math parser to get the
        current memory address
       -added dcb/dcw/dcd directives
I also extended the readme quite a bit, many more things are explained now. This will probably be the last new feature for a while, but I will add PS2 support eventually.


There are several bugs in the current release. One of these is that using an ldr= ARM/THUMB opcode without defining a pool after it causes the assembler to crash.
Additionally, quite a few ARM opcodes are missing...

-ldrh/sh/b and strh/sh/b don't work with post indexing, be it register or immediates
-ldrh/sh/b and strh/sh/b also don't work with negative pre indexing or writebacks
-there also no pc relative variants for them (ie ldrh r0,[Label])
-no ldr/str variant at all works with negative register pre or post indexing

If there are more that I missed, it would be great if you could report them so that I can fix them for the next release.

On the bright side, I've added a few new things since the last version. Macros can now contain local labels that will get an unique name every time the macro is used, there is a new area directive that ensures that the data doesn't cross a specified boundary and there are also directives that output a warning/error to the console (useful for nested if/else blocks).


Is source available should your harddrive/you die? I'm sure it would be a fairly trivial port to posix.


Great job!
Looking forward to the PS2 Support version. PS2 never gets any hacking attention these days =(


I think I'm getting closer to the next release.

Here's a list of the changes since the last version:

  • many, many fixes to the ARM instruction set
  • new directives, like the area directive that checks for overflows, and debug message support for no$gba and ideas
  • macos can contain local labels
  • sym support completed, the file now contains all the possible information (also for use with no$gba):
  • and also many bug fixes

The next release should be an overall improvement, and also much more stable. I just need to test it more.
Extended MIPS support won't make it into the next version, unfortunately, but I'm still open to feature requests.


Best assembler ever. Keep up the good work and I hope to see PS2 support sooooon!  :woot!:


The new version has been released:

    * macros can now contain unique local labels
    * area directive added
    * added missing ARM opcode variations
    * countless bugfixes
    * no$gba debug message support
    * full no$gba sym support


a few complaints for the arm support, you dont seem to support the pseudo opcode adr nor can i use pc relative addressing on ldr
for example:
ldr r1, label
label: .word 0

should convert the ldr into ldr r1, [r15,-4] but all i'm getting is errors. If you could fix that and add support for the adr opcode this would be perfect :)

EDIT: looks like i can make a quick little macro for adr
.macro adr,destReg,Address
   .if (here & 2) != 0
      add destReg, r15, (Address-here)-2
      add destReg, r15, (Address-here)

also looks like i fixed my problems with ldr


Thanks for the feedback.

There's currently no adr opcode, yeah. I didn't about this one as I used the no$gba specs to implement everything. There is a slightly different opcode with the same functionality though.
PC relative stuff can be done this way:

add r0,=label ; pc relative adds
ldr r1,[label]  ; pc relative loads
label: .word 0

I'll add adr to the next version, but I think it's better to keep all ldr opcodes with brackets.

For the next version, I have also implemented a few optimizations. immediate loads will be converted to mov/mvn if possible, and mov/mvn, and/bic, and cmp/cmn will all try to use the other one if possible and necessary. So these two will result in identical code:
and r1,0xFFFFFFFE
bic r1,1

Edit: Damn. I'm sorry, it looks like there is no add= after all... I was sure I implemented it. I'll definitely add it for the next version.
The math parser also supports "." as a replacement of the current position, so you could use it instead of the "here" label.

So something like this:
.macro adr,destreg,address
add destreg,r15,address-.

Edit2: I DID implement it, but only in Thumb mode.


Another bug to report.

.org 0x08FFFD00
;LDRB    R0, [R4,#6]
;ADDS    R0, #1          ; patch this mother fucker for number of oam entries

ldr     r0, [currentChar2]
ldrb    r0, [r0]

STRB    R0, [R4,#6]
MOV     R0, #1
STRB    R0, [R4,#1]

LDR     R0, [R4,#0x4C]
ADD     R0, #2
;STR     R0, [R4,#0x4C]

bx      lr

If I remove the commented line it assembles fine but if its there armips seems to hang, I'm not sure why either its happened a few times now on various opcodes.

EDIT: Apparently if i change the ADD R0,#2 into two ADD r0,#1 with that STR uncommented it assembles fine, possibly some sort of weird alignment issue?

Prof. 9

I'm having a bit of trouble with the area directive; it's making ARMIPS crash without error messages or "Done" for me.

I made a bunch of free space offset labels, like this:

fspace1 equ 0x08000000
fspace2 equ fspace1+n
fspace3 equ fspace2+n
fspace4 equ fspace3+n
fspace43 equ fspace42+n
fspace44 equ fspace43+n
fspace45 equ fspace44+n

If, for n, I use a 16-bit number at least 28 (0x1C) times, the following piece of code will cause the assembler to crash:

.area fspace45-fspace44

However, the following will assemble without a problem:

.area fspace44-fspace43
.area fspace45-fspace43
.area n ; n = fspace45 - fspace44

If you're wondering, the reason why I'm using such a system is because I'm working on a translation project and this setup lets me not have to worry about free space addresses, just about the size of the data loaded into free space (which is checked by the area directive).

I've removed all irrelevant files and opcodes from my project to make a small environment for testing, which can be found in the link below. If "fspaceN.asm", where I used a 16-bit number 28 times, is .included in "src.asm", the assembler will crash. In "fspaceY.asm", I used a 16-bit number only 27 times, and it works with that.

Test case:


Thanks for the detailed bug report! I located the error and I'll send you a PM with a fixed test build shortly.


Is there a way to remove the automatic Nop command after each branch/jump ?


There are no automatic nops after branches. The only time nops are automatically inserted is when you use .fixloaddelay and have a MIPS load delay issue (accessing data before it's ready). If something other than that happens, it would be nice if you could provide a sample.


Ok, it's just a bad habit, I was a bit tired I guess and I'VE put the nop...  thanks anyway  ;)


I've been working on it again lately. Fixed several mistakes in the ARM instruction set, and added a new label type, the static labels. These are global labels, but they are only valid in the very file that defined them. Not in any file that includes them and not in any file that is included. Therefore these names can be reused in different files. They are defined with a single leading @.
I also started working on PS2 support. This requires many internal changes and will need a lot of good testing. The instruction set is huge, and many of the opcodes are exclusive to the PS2 and not supported by anything else (mostly the vector and mmi instructions).
If anyone's got experience working with PS2 assembly code, it would be great if he could help testing.


btw, do you have any comprehensive listing of ps2 opcodes?

i have a couple of EE docs, but i am not sure how complete they really are. i stumbled across some unlisted instructions when disassembling a couple of executables, and i wonder if my docs are incomplete, or the tool got confused.


I'm mostly using the PCSX2 source code to see how all the opcodes are encoded and what format they are in. It's hard to find decent documentation for such an obscure CPU.