Looking for guideance on PS2 MIPS assembly

BenoitRen

Active Member
OP
Newcomer
Joined
Jul 1, 2015
Messages
40
Trophies
0
Age
38
XP
142
Country
Belgium
Hi everyone

I'm decompiling a PS2 game by reading MIPS assembly and converting it to C, and would like some help with understanding some peculiar patterns I'm coming across. Most of it seems to be related to global variables.

For example:
Code:
lui          v1,hi(actwk+256)
addiu        v1,v1,lo(actwk+13696)
This puts the address of the global variable actwk in register v1, but I can't understand how! Why is it taking the upper part of offset 256, base actwk? Then it adds the lower part of offset 13696, base actwk. What's puzzling is that 13696 is the memory address of said global variable. It doesn't make any sense!

Something similar seems to be happening here to make a function call:
Code:
lui          v0,hi(sMemSet+256)    ; v0 = hi(sMemSet+256)
lw           v0,lo(sMemSet)(v0)    ; v0 = lo(sMemSet+v0)
jalr         ra,v0
Can anyone help me? The PS2 homebrew seems to be mostly dead.
 

FAST6191

Techromancer
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,348
Country
United Kingdom
Are PS2 games originally written in C? Would have thought most would have been C++ by this point. Some of the things below do have sections on C though so I will skip that one for now. Hope it is though as that will allow the decompilation train to keep on going for a wider range than I thought it might.

Anyway how many around here are deep into PS2 MIPS I don't know, don't imagine it is many though.

MIPS R3000A then. I have very limited time with this (any MIPS I have done has mostly been the more primitive N64, certainly have not done a comparison between them) but can give it a shot.
https://vhouten.home.xs4all.nl/mipsel/r3000-isa.html
https://web.archive.org/web/20061010210946/http://decstation.unix-ag.org/docs/ic_docs/3715.pdf

lui and addiu instructions.
The second link in chapter 9 notes that three registers are a thing (hopefully same syntax between them) which is somewhat unusual for most things I deal with. Anyway order seems to be destination, first register, second register.
Load Upper Immediate
Add Immediate Unsigned Word (the add command it seems have a variety of options depending upon input type)

On lesser CPUs having something made part by part from things is common enough; hard to fit a full register worth of immediate value when your instruction is the same length as a register and needs to have enough bits to indicate it is an instruction, assuming nothing cute can be done with inverters (need all FF in there and mov with an invert can get it done as the baseline will be assumed to be 0) then either you get to fiddle with shift commands or hope there is something that can fiddle with the upper bits with this seemingly being the latter (ARM tends to be shift). Now I am not sure what you are asking, or is this you being used to modern clever compilers and not the "that'll do" ones of the day (PS2 was a step up from earlier stuff but still nothing like you might see today on PC or something). Seems something like that might also be going on here (page 150, or 9-3, covering some of this)... some of this almost feels like really old school assembly with relative jumps having maximum distances.
 

BenoitRen

Active Member
OP
Newcomer
Joined
Jul 1, 2015
Messages
40
Trophies
0
Age
38
XP
142
Country
Belgium
Thanks for your response.

What I'm decompiling is Sonic CD, which is part of Sonic Gems Collection. The reason it's C instead of C++ is because it is actually a port of the PC version created back in 1995 by Sega of Japan in collaboration with Intel.

I didn't understand why it took two steps to load the memory address of a global variable, with the first instruction seemingly unrelated. I've since found out that it's like you said: "On lesser CPUs having something made part by part from things is common enough; hard to fit a full register worth of immediate value when your instruction is the same length as a register".

The first instruction loads the upper part of the address, while the second instruction loads the lower half.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • No one is chatting at the moment.
    Sonic Angel Knight @ Sonic Angel Knight: :ninja: