News: 11 March 2016 - Forum Rules

Author Topic: Branching in Disassembled Code  (Read 6247 times)

tryphon

  • Hero Member
  • *****
  • Posts: 736
    • View Profile
Re: Branching in Disassembled Code
« Reply #20 on: September 03, 2015, 05:44:43 pm »
I'd bet Street Fighter 2 was also written in some kind of C (at least MD version, but won't be surprised if all versions shared more or less the same code).

AnderHershey

  • Jr. Member
  • **
  • Posts: 10
    • View Profile
Re: Branching in Disassembled Code
« Reply #21 on: September 04, 2015, 02:40:31 am »
Quite a few long nights and a lot of lines transcribed, I now have a few more questions. Forgive me if I'm asking too much, personally I wish there was a way to ask quick questions without making something as big as a "post" on a forum.

So, in a routine I found, it jumps to a location.
This location does have stuff, and I wrote it all out.
While using the debugger I set the zero flag such that I'd
land on the JSR that would send me to the location in order
to check a few things.
Upon doing so though I got a completely different set of instructions.
I then picked one of the instructions, looked it up in the
hex editor, and found only one instance of it.
I was like "Ok this has everything the same except for the first byte".
meaning, of XXXX the one on the far left is different.
I then thought, ok, maybe something jumps here.
So I just look up the address to where it'd jump, leaving
the first part wild card since I don't know what type of jump
they might use to get here.
Even then, nothing appeared except for things where it wasn't a jump command.
At this point I was hoping I had written something wrong, but I hadn't.
So I don't know what to do.
The jump instruct in the hex is JSR B767.
In test code it's
0b767 (where the next instruction starts)
this next instruction, the one it starts at after the JSR,
occurs only in one location in the rom though, and that is at 3767.

Also, as an aside, PLB, from the manual on the langauge,
pulls the top 8 byte of the stack and has it replace B register
which stores the bank one is currently in.
I could see this holding purpose if one needed to get back to
a location without a JMP (since maybe the location is variable),
but then they proceed to RTL, which should return them to where
they want regardless of the bank they are in.
(I am assuming that since JSL can go "anywhere", RTL can return "anywhere").
I guess if the return location is on the stack and was stuck under
the bank data register 8 bits I can see that being a reason to PLB
before RTL, but beyond that, I don't see why.

update on the last part:
So, if when one JSL's it pushes the address lets say the current address location is 018040 the when it's put on the stack it's:
40 placed, 80 placed, and lastly 01 placed.
In this idea, PLB will take the 01, and then RTL takes the 8040 to return. (this is if RTL doesn't incorporate the bank for some reason, even though JSL does).

And as a final addition:
Also, one of my JMPs, JMP 8D70, which in test code goes to there (in the debugger), but that location would be 0D70.
Since the JMP is evident in the hex, I feel like that should head to 8D70, but the test code shows otherwise. So I don't know why what I debug and step through gives different from logical progression from finding the breakpoints, finding them in hex, finding corresponding jumps, and following manually.

edit: Upon looking at:
ASM Hacking for Dummies
I noticed 5.1 so I think that might have something to do with these issues.
« Last Edit: September 04, 2015, 03:28:24 am by AnderHershey »

AWJ

  • Full Member
  • ***
  • Posts: 105
    • View Profile
Re: Branching in Disassembled Code
« Reply #22 on: September 04, 2015, 06:00:20 am »
Quite a few long nights and a lot of lines transcribed, I now have a few more questions. Forgive me if I'm asking too much, personally I wish there was a way to ask quick questions without making something as big as a "post" on a forum.

So, in a routine I found, it jumps to a location.
This location does have stuff, and I wrote it all out.
While using the debugger I set the zero flag such that I'd
land on the JSR that would send me to the location in order
to check a few things.
Upon doing so though I got a completely different set of instructions.
I then picked one of the instructions, looked it up in the
hex editor, and found only one instance of it.
I was like "Ok this has everything the same except for the first byte".
meaning, of XXXX the one on the far left is different.
I then thought, ok, maybe something jumps here.
So I just look up the address to where it'd jump, leaving
the first part wild card since I don't know what type of jump
they might use to get here.
Even then, nothing appeared except for things where it wasn't a jump command.
At this point I was hoping I had written something wrong, but I hadn't.
So I don't know what to do.
The jump instruct in the hex is JSR B767.
In test code it's
0b767 (where the next instruction starts)
this next instruction, the one it starts at after the JSR,
occurs only in one location in the rom though, and that is at 3767.

CPU addresses aren't the same as offsets in the ROM. You need to understand the SNES memory map. Within each bank:

$0000-1FFF is RAM
$2000-7FFF is memory-mapped I/O (registers controlling video, sound, DMA, etc.) and cartridge-specific stuff (e.g. battery RAM)
$8000-FFFF is ROM

The exceptions are banks $7E and $7F which are entirely RAM, and banks $40-7D and $C0-FF which are entirely ROM.

The first $8000 bytes of ROM are mapped at $8000-FFFF in bank 0, the next $8000 bytes are mapped at $8000-FFFF in bank 1, the next $8000 bytes in bank 2, et cetera.

To convert a CPU address to a ROM position: Take the non-bank part of the address, subtract $8000 from it, then multiply the bank number by $8000 and add it. If the non-bank part of the address is less than $8000 then the address isn't in the ROM at all, it's in RAM or it's a memory-mapped register.

So a JSR $B767 in program bank 0 will indeed jump to offset $3767 in the ROM.

To convert a ROM position to a CPU address do the reverse: the bank number is the ROM offset divided by $8000, and the address within the bank is $8000 plus the offset modulo $8000.

(All of this applies to Mode 20 aka LoROM, the most common type of SNES cartridge. There is another type called Mode 21 or HiROM that is mapped differently. Don't worry about it for now. I can tell from your description that the game you're disassembling is LoROM and not HiROM)

Quote
Also, as an aside, PLB, from the manual on the langauge,
pulls the top 8 byte of the stack and has it replace B register
which stores the bank one is currently in.
I could see this holding purpose if one needed to get back to
a location without a JMP (since maybe the location is variable),
but then they proceed to RTL, which should return them to where
they want regardless of the bank they are in.
(I am assuming that since JSL can go "anywhere", RTL can return "anywhere").
I guess if the return location is on the stack and was stuck under
the bank data register 8 bits I can see that being a reason to PLB
before RTL, but beyond that, I don't see why.

The program bank and the data bank are two different registers. The program bank is where code is executing from--think of it as an extra 8 bits on top of the program counter. The data bank determines which bank the data is accessed from when you do LDA, STA, etc. If the CPU does LDA $1234 and the data bank is $7E, the full address it loads the data from is $7E1234. PHB and PLB affect the data bank, not the program bank.