News:

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

yoshi314

hmm, it would never occur to me to look at pcsx2. thanks for the hint.

i mostly tried using this doc to help me out http://www.herrvillain.com/codebreaker/inst_0e.pdf

Klarth

Well that's interesting.  I didn't know the FPU had DSP-like multiply-add functions nor about the EE's SIMD-type instructions.  I guess I never paid attention to them in my brief stint.

Pokeytax

This is a good program, thanks.

I am trying to write raw hex for a table. How on earth do I use the .byte command? I don't know how I'm screwing up something so simple.

Normmatt

Quote from: Pokeytax on February 10, 2012, 07:12:25 PM
This is a good program, thanks.

I am trying to write raw hex for a table. How on earth do I use the .byte command? I don't know how I'm screwing up something so simple.

.db $56
.db 0x56
.db 86

Prof. 9

Small oddity: the following is all happily accepted:

dcb   0x5511111111
.db   0x5522222222
dcw   0x5533333333
.dw   0x5544444444

The above assembles into 11 22 33 33 44 44 44 44, oddly. Anyway, I can't think of a single legitimate use for this, so perhaps it's a good idea to return an error message if the value to be written is too high?

EDIT: This is for the version you gave me in August last year.

KC

There's no benefit freem restricting that. The whole expression parser is designed to work like in standard C/C++ code, so it would just be logical that such writes do the same. It could be used to store pointers that aren't saved in one consecutive piece, without having to use a bitmask to clear the upper bits all the time.
Such range checks of course can be complicated, too. -1, for example. Technically it fits into 8 or 16 bits, but internally it's just a huge positive 32 bit number, the same as 0xFFFFFFFF.

In other news, I've worked on some bigger internal redesigns and the next version, whenever it will be finished, will be able to load PS2 (and maybe PSP) executables and automatically read the sections from the file to acquire the memory mapping. The R5900 instruction set will of course also be supported. But that will still take quite a while.

x0_000

#46
Version 0.7c of ARMIPS switches the ldrh and ldsb instruction for GBATEK, in the sense that it compiles

ldrh r1, [r2, r3]

into

ldsb r1, [r2, r3]

and vice versa. I haven't checked the other versions of ldrh for this bug, but it looks like you just switched a case check for that instruction set, none of the other instances of ldrh can be confused with ldsb. Great job with the assembler otherwise, it's pretty awesome! Just need to comb the readme more thoroughly to unlock its FULL POTENTIAL

EDIT: Just noticed this now, the assembler doesn't yell at me when I tell it to assemble

add, r7, r0

it just gives gibberish! D: partially my fault for forgetting how add instructions work :P

KC

Thanks for the bug report.
Trying to assemble "add, r7, r0" results in an error that "add," is not a valid opcode. That's what should happen. "add r7, r0" would be assembled as "add r7,r0,r0".
I couldn't replicate the wrong opcodes, and there have been no changes to them since the last release in 2010. Is that with THUMB or with ARM opcodes?

x0_000

Sorry, I meant

add r7, r0

does not get assembled into something legal (the GBA disassembler doesn't recognize it) but the assembler doesn't abort/throw an error. The ldrh bug is with THUMB opcodes. For a specific instance,

ldsb r0, [r4, r0]

gets assembled into

ldrh r0, [r4, r0]

KC

It seems that the add is assembled as the "Hi register operation", normally used for changing/reading r8-r15. Technically, it should be legal and it should work (no$gba emulates it correctly as well), but I guess most disassemblers don't expect it there, and would rather like to see the normal add for the lower half of the registers. I'll look into changing that.
But I still can't replicate the other one. no$gba is showing both correctly, and it's just as GBATEK says as well. Are you sure about it?

x0_000

I'm pretty sure because I assembled some code with a ldrh instruction and I kept getting the wrong output (very wrong!), and when I debugged it in VBA I noticed the ldsb instruction.

Spoiler
.open chivalry-test.gba,0x0

.gba
.thumb

.org 0xded060
push {r4,lr} ; pulls skill from 0x08016764
add r4, r0, 0x0
add r2, pc, 0x8
add r2, 0x1
mov lr, r2
ldr r2, =0x08016765
bx r2
.align

lsl r0, r0, 0x10
lsr r2, r0, 0x10
ldr r0, [r4, 0xc]
mov r1, 0x10
and r0, r1
cmp r0, 0x0
bne rescue ; (checks if unit is rescuing someone)

add r0, r2, 0x0
add r2, pc, 0x8
add r2, 0x1
mov lr, r2
ldr r2, =0x08016099 ;08018b08 bl $08016098 f7fdfac6
bx r2
.align
add r1, r0, 0x0
mov r0, 0x15 ;loads skill
ldsb r0, [r4, r0] ;bug, should be ldrh
b noRescue

rescue:
add r0, r2, 0x0
add r2, pc, 0x8
add r2, 0x1
mov lr, r2
ldr r2, =0x08016099 ;08018b08 bl $08016098 f7fdfac6
bx r2
.align

add r1, r0, 0x0
mov r0, 0x15 ;loads skill
ldsb r0, [r4, r0] ;bug, should be ldrh
ldr r2, [r4, #0x4] ;loads class pointer
ldrb r2, [r2, #0x5] ;loads class ID at 0x5!!!

cmp r2, 0x14
beq chivalry

cmp r2, 0x15
beq chivalry

cmp r2, 0x16
beq chivalry

cmp r2, 0x17
beq chivalry

lsr r2, r0, 0x1f
add r0, r0, r2
asr r0, r0, 0x1
chivalry:
noRescue:
add r0, r0, r1
pop {r4}
pop {r1}
bx r1
.pool

.close

;blank line

[close]

This is the code I assembled, the 4th block has a "bug, should be ldrh" comment (there are a few more peppered throughout), but it assembles the ldsb instruction into an ldrh.

KC

According to this: http://vba.cvs.sourceforge.net/viewvc/vba/VisualBoyAdvance/src/armdis.cpp?view=markup
VBA implements it as:
// Format 8
{0xfe00, 0x5200, "strh %r0, [%r3, %r6]"},
{0xfe00, 0x5600, "ldsb %r0, [%r3, %r6]"},
{0xfe00, 0x5a00, "ldrh %r0, [%r3, %r6]"},
{0xfe00, 0x5e00, "ldsh %r0, [%r3, %r6]"},

Which is also what I get.
"ldsb r0, [r4, r0]" is assembled as 0x5620, and "ldrh r0, [r4, r0]" as 0x5A20.

Aside from that, I'd recommend to use ".open old,new,address", where old is an existing untouched copy and new a file that will be created by the assembler. You should also use the correct memory address, 0x8000000. Relative branches work either way, but pointers would be incorrect.

x0_000

...huh. VBA's disassembler *is* disassembling it incorrectly. My bad! Sorry for wasting your time on that  :-[

Prof. 9

Is there any chance an .include and .import/.incbin for files relative to the current file could be added (as opposed to relative to where ARMIPS was called)? I'm using ARMIPS for fairly large projects and it seems kind of counterintuitive to have to include the whole path each time, and it also makes it annoying to reorganize things since moving or renaming a folder will break EVERYTHING in that folder. It also destroys any sort of modularity.

KC

I've sent you a PM with a version that supports it. If it works without errors, I could probably release it to the public, too.

x0_000

Bug with v0.7c; Doing something like the following:

foo equ 1 + 2
bar equ foo*4

makes bar = 1+2*4 = 9, instead of (1+2)*4 = 12.

KC

equ is a pure text replacement, much like #define in C. You can put parentheses around it though.

x0_000

Oh, I see. You should clarify that in the readme, I've never used a feature like that while programming :P

KC

It actually does say so there.

Quote
3.4  equ

This works as a text replacement and is defined as follows:

  @@StringPointer equ 0x20(r29)


There has to be a space before and after equ. The assembler
will replace any occurance of @@StringPointer with "0x20(r29)".

x0_000

Sorry, I meant clarifying that text replacement doesn't have the behavior of variable assignment (which is what I've been using it as!)