Help Thread ASM & Disassembly Page 16

Started by Spherical Ice December 1st, 2014 11:05 AM
  • 65283 views
  • 626 replies
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.9 Years
So I wrote a routine that hooks from the givepokemon function to allow for the level of the given Pokémon to be loaded from a variable. A quick check in VBA-SDL-H shows that it hooks alright and runs till the end just as it should. Upon trying to return to the givepokemon function again (through a pop {pc}), though, the game begins loading from the BIOS header and, naturally, crashes. JPAN actually mentions this problem as a common pitfall to avoid in his THUMB tutorial, but I can't seem to understand what's causing it to happen here. Something obvious, no doubt.

Here's what my code looks like:
hook @0x0806BFF0:
Spoiler:
.text
.align 2
.thumb
.thumb_func

main:
	ldr r2, =(0x0880322D)
	bx r2

.align 2

routine @0x0880322C:
Spoiler:
.text
.align 2
.thumb
.thumb_func
	@hooks from givepokemon function; if Pokémon's level is set to 0xFF in XSE, level is
	@loaded instead from var 0x8001, -3, -5, -7, -9 or -B, according to the player's
	@multichoice selection, and stores it in r1. Proceeds as normal otherwise.

main:
	ldrb r1, [r0, #0x0] @loads level of Pokémon to be given into r1
	cmp r1, #0xFF
	BNE end @jumps to end if Pokémon's level is not 255
	
	push {r0, r3}
	ldr r0, =(0x020370BA) @var 0x8001; contains level of Pkm1
	ldr r2, =(0x20370D0) @LASTRESULT; contains Player's multichoice selection
	ldrb r2, [r2]
	mov r3, #0x0 @initializes iterable
	
loop:
	cmp r2, r3
	BEQ loader
	add r0, #0x4 @moves to location of next variable (containing level of Pkm)
	add r3, #0x1
	b loop
	
loader:
	ldrb r0, [r0]
	mov r1, r0 @stores byte loaded from variable into r1
	pop {r0, r3}
	
end: 
	mov r2, r0 @restores r2 to its original value (pointer to script location)
	
	@original instructions from givepokemon removed for hook:
	mov r9, r1
	add r0, #0x1
	str r0, [r4, #0x8]
	add r0, r4, #0x0
	pop {pc}
.align 2
POP {PC} will take the top value on the stack and set PC to that. If LR was the last register that was pushed, this will return you. However, since you're hooking, you're in the middle of a routine. What you want to do is BX back to the routine your're hooking into.

From the location of your hook, I assume you'd want to do this instead of POP {PC}

ldr r1, =(0x0806BFFA + 1)
bx r1
This will take you back to the BL script_read_halfword.

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.

colonelsalt

Guaranteed to raise the smile

Age 25
Male
London
Seen 20 Hours Ago
Posted March 24th, 2023
111 posts
10.5 Years
Thanks a ton; I really appreciate the help. I assumed there was a conceptual understanding I was just not getting here. Routine works perfectly now with your solution. I had somehow gotten into my head that you couldn't bx to an offset that's not word-aligned, but I guess that's not an issue.
As a side note, am I correct in assuming that sticking to the pop {pc} would still not work even if I did push {lr} at the start of my routine, because calling by bx does not influence the link register? Could using a bl-bx combo in the hook itself, then, circumvent having to load the pointer to the return location in the routine itself? Just trying to wrap my head around this.
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.9 Years
Thanks a ton; I really appreciate the help. I assumed there was a conceptual understanding I was just not getting here. Routine works perfectly now with your solution. I had somehow gotten into my head that you couldn't bx to an offset that's not word-aligned, but I guess that's not an issue.
As a side note, am I correct in assuming that sticking to the pop {pc} would still not work even if I did push {lr} at the start of my routine, because calling by bx does not influence the link register? Could using a bl-bx combo in the hook itself, then, circumvent having to load the pointer to the return location in the routine itself? Just trying to wrap my head around this.
Well, you're almost right. You can't BX to a routine that isn't halfword aligned. The LSB is just used to mark THUMB code. Routines don't actually have to be word aligned. Literal pools must be word aligned on the other hand (that's why you .align 2 before any .words).

If you did BL then BX to your hook code, the calling routine would set LR = PC + 4 on the BL. So when you return via popping LR onto PC, BX LR, etc. you would move to the instruction directly after the BL. Since your hook code overwrites some stuff, this would not work as intended:

ldr rX, =(HOOK_ADDR)
bl linker
;; Return here

linker:
   bx rX
Since it returns there, you'd return and encounter the "bx rX" under the linker label, which would end up crashing. You could solve this by putting a relative branch underneath, but why bother? This routine above uses 12 bytes, 14 (maybe even 16, depending where the literal pool is placed) with an additional branch to make it work. Standard hook code uses 8 bytes on a word aligned address. You generally want the hook code to be the most compact so you can put it anywhere. Losing 8 bytes of free space to branch back doesn't really matter all that much.
Additionally, manually returning allows more control over where you return to. This can be useful if your hook code forces some routine to exit early if a certain condition is true.

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
Male
Seen June 23rd, 2018
Posted December 27th, 2017
154 posts
8 Years
Hi Guys I need to ask that I am making an ROM hack of ash adventure from kanto to hoenn region.
I am hacking fire red ROM,but fire red contain only kanto region badges cammands and there is no jotho and hoenn region badges cammands and there is no space on trainer card for more badges and no pic for jotho and hoenn badges so I know it can be added and down by ASM
So I want help in ASM in making this ASM so there will an Jotho and hoenn badges will available
Please replay me I need help in this to continue my hack please help and reply

BadEgg~

Pokémon: Volant Version Developer

Male
Pokémon PC Network
Seen September 11th, 2017
Posted September 11th, 2017
112 posts
7.8 Years
I'm looking into getting into ASM hacking, as my current project is one that's aimed at being a more "refreshing" experience rather than the typical "10 year old solo's the entire country and defeats grown adults etc.".

Would any of you know any tutorials for ASM hacking? Videos are not required, but are a big bonus (a lot of images that are included in text guides eventually are pulled down).
Current Projects
---

Mana

Age 31
Male
UK
Seen March 25th, 2023
Posted August 18th, 2021
10,075 posts
14.3 Years
I'm looking into getting into ASM hacking, as my current project is one that's aimed at being a more "refreshing" experience rather than the typical "10 year old solo's the entire country and defeats grown adults etc.".

Would any of you know any tutorials for ASM hacking? Videos are not required, but are a big bonus (a lot of images that are included in text guides eventually are pulled down).
Try this. I've heard FBI has left pokecommunity (and possibly hacking in general) now but it should still be helpful ><.
Male
São Paulo, Brasil
Seen November 1st, 2021
Posted September 7th, 2019
275 posts
8 Years
Sup guys.
This is daniilS' routine for the Heal Ball:
Spoiler:
.text
.align 2
.thumb
.thumb_func
.global afterpoketranscalc

main:
	push {lr}
recycle:
	ldr r3, memcpy
	bl bxr3
calc:
	cmp r7, #0x64
	bne ender
	ldr r3, somevar
	ldrb r3, [r3]
	cmp r3, #14	/*ball index of heal ball here*/
	bne ender
healstuff:
	ldr r3, poke_quantity
	ldrb r1, [r3]
	mov r10, r1
	mov r1, #1
	strb r1, [r3]
heal_recycle:
	mov r3, pc
	add r3, #0x1d
	push {r3}
	push {r4-r7}
	mov r7, r10
	mov r6, r9
	mov r5, r8
	push {r5-r7}
	sub sp, sp, #4
	mov r1, #0
	mov r8, r1
	mov r1, r0
	mov r10, r1
	mov r6, sp
	ldr r3, healpoke
	b bxr3
heal_finish:
	ldr r3, poke_quantity
	mov r1, r10
	strb r1, [r3]
ender:
	pop {r3}
bxr3:
	bx r3

.align 2
	memcpy:			.word 0x081e5e78+1
	somevar:		.word 0x0203fe00
	partyadr:		.word 0x02024284
	poke_quantity:		.word 0x02024029
	healpoke:		.word 0x080a0076+1

I got a few questions. If I only want it to heal half the Pokémon's HP, I'll need a new "healpoke" routine, right?
By just changing the to-be-made "halfhealpoke" with the "healpoke", it will work alright?

Also, I wanna make it work for every Pokéball, not actually intending to put a Heal Ball in the game.
daniilS told me that if I simply delete the line with the ball index of the Heal Ball, it will work for every other ball.
His post:
You can easily change the ball index check in the healing routine, or remove it altogether if you want it to work for every ball.
But don't I need something in the battle script after capturing a Pokémon to call this routine? Or it runs automatically after I catch a Pokémon?
My Main Team:


daniilS

busy trying to do stuff not done yet

Age 23
Male
Seen March 2nd, 2021
Posted October 7th, 2015
409 posts
9.8 Years
I got a few questions. If I only want it to heal half the Pokémon's HP, I'll need a new "healpoke" routine, right?
By just changing the to-be-made "halfhealpoke" with the "healpoke", it will work alright?
The thing is, the healing is done by calling the party healing routine and making it only work on the caught poke. Perhaps writing a custom routine would work better if you only want it to restore half its HP.
Also, I wanna make it work for every Pokéball, not actually intending to put a Heal Ball in the game.
daniilS told me that if I simply delete the line with the ball index of the Heal Ball, it will work for every other ball.
His post:

But don't I need something in the battle script after capturing a Pokémon to call this routine? Or it runs automatically after I catch a Pokémon?
The ball hacking thread tells you how to activate this routine.
Male
São Paulo, Brasil
Seen November 1st, 2021
Posted September 7th, 2019
275 posts
8 Years
I got a few questions. If I only want it to heal half the Pokémon's HP, I'll need a new "healpoke" routine, right?
By just changing the to-be-made "halfhealpoke" with the "healpoke", it will work alright?
The thing is, the healing is done by calling the party healing routine and making it only work on the caught poke. Perhaps writing a custom routine would work better if you only want it to restore half its HP.
Also, I wanna make it work for every Pokéball, not actually intending to put a Heal Ball in the game.
daniilS told me that if I simply delete the line with the ball index of the Heal Ball, it will work for every other ball.
His post:

But don't I need something in the battle script after capturing a Pokémon to call this routine? Or it runs automatically after I catch a Pokémon?
The ball hacking thread tells you how to activate this routine.
But if I write a custom routine for half healing a Pokémon, would I activate it the same way as the ball hacking thread explains?
Or I just call this custom routine I'd make from yours, instead of healpoke?
My Main Team:


Seen November 20th, 2016
Posted November 20th, 2016
417 posts
8.2 Years
How do I write a branch to a specific offset? When I try to overwrite existing routines and use a format like:

.org 0x08XXXXXX
stuff here
b 0x08YYYYYY

although it assembles at the offset 0x08XXXXXX and 0x08YYYYYY is well within the branch range (only like 100 bytes away from pc), the b 0x08YYYYYY, on DevkitARM at least, just assembles as branching to itself. I've been using opcodes for those instructions, but surely that isn't an efficient method. Even a method that lets me write out something like "branch + 24 bytes" would be a lot better than what I'm using right now.
Male
Seen February 1st, 2018
Posted October 19th, 2017
625 posts
8.9 Years
How do I write a branch to a specific offset? When I try to overwrite existing routines and use a format like:

.org 0x08XXXXXX
stuff here
b 0x08YYYYYY

although it assembles at the offset 0x08XXXXXX and 0x08YYYYYY is well within the branch range (only like 100 bytes away from pc), the b 0x08YYYYYY, on DevkitARM at least, just assembles as branching to itself. I've been using opcodes for those instructions, but surely that isn't an efficient method. Even a method that lets me write out something like "branch + 24 bytes" would be a lot better than what I'm using right now.
While I don't think you can use precise offsets/addresses, you can use arithmetic on labels and symbols, so try "$+OFFSET", ".+OFFSET" (relative to the current instruction) or use a label and mark it relative to that with "label+OFFSET". It seems that any undefined symbol (with a valid name) is treated as ".", which is the special symbol reserved to mean the current address.

Keep in mind that .org doesn't really work so well for that purpose and will cause your output binary to be padded with zeroes. See http://tigcc.ticalc.org/doc/gnuasm.html#SEC112

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.

daniilS

busy trying to do stuff not done yet

Age 23
Male
Seen March 2nd, 2021
Posted October 7th, 2015
409 posts
9.8 Years
How do I write a branch to a specific offset? When I try to overwrite existing routines and use a format like:

.org 0x08XXXXXX
stuff here
b 0x08YYYYYY

although it assembles at the offset 0x08XXXXXX and 0x08YYYYYY is well within the branch range (only like 100 bytes away from pc), the b 0x08YYYYYY, on DevkitARM at least, just assembles as branching to itself. I've been using opcodes for those instructions, but surely that isn't an efficient method. Even a method that lets me write out something like "branch + 24 bytes" would be a lot better than what I'm using right now.
Here's an example of how I deal with this cases. Here it's an extension of a set of compares for screen darkening because of OW weather effects:
.thumb
.equ loc,	0x0807A872
.equ nofade,	0x0807A880
.equ next,	0x0807A882
extracheck:
	cmp r0, #5
	beq nofade-loc
recycle:
	mov r2, #1
	b next-loc
Instead of using equs you could also just put the offsets in the routine itself, because it's the +/- that matters here if I'm right.
Seen November 20th, 2016
Posted November 20th, 2016
417 posts
8.2 Years
Here's an example of how I deal with this cases. Here it's an extension of a set of compares for screen darkening because of OW weather effects:
.thumb
.equ loc,	0x0807A872
.equ nofade,	0x0807A880
.equ next,	0x0807A882
extracheck:
	cmp r0, #5
	beq nofade-loc
recycle:
	mov r2, #1
	b next-loc
Instead of using equs you could also just put the offsets in the routine itself, because it's the +/- that matters here if I'm right.
Hmm. If I'm understanding what you did correctly, are each of those .equ, despite being real (sort of defines?), only being used for simple arithmetic? As in..... your "b next-loc" is basically branch + 0x10 bytes in a more legible way? Regardless, what assembler did you use for that? I quickly tested out what you wrote with DevkitARM and at the end of my bin, I saw the all too familiar FE E7 (a branch to itself). Touched's suggestion of label + offset worked, but when it comes to b/bl/beq etc. to any actual addresses, I haven't been able to assemble anything involving +/- that doesn't literally include a number on the line. Not that it matters too much I suppose; it would just be easier to read.

daniilS

busy trying to do stuff not done yet

Age 23
Male
Seen March 2nd, 2021
Posted October 7th, 2015
409 posts
9.8 Years
Hmm. If I'm understanding what you did correctly, are each of those .equ, despite being real (sort of defines?), only being used for simple arithmetic? As in..... your "b next-loc" is basically branch + 0x10 bytes in a more legible way? Regardless, what assembler did you use for that? I quickly tested out what you wrote with DevkitARM and at the end of my bin, I saw the all too familiar FE E7 (a branch to itself). Touched's suggestion of label + offset worked, but when it comes to b/bl/beq etc. to any actual addresses, I haven't been able to assemble anything involving +/- that doesn't literally include a number on the line. Not that it matters too much I suppose; it would just be easier to read.
Yeah, I'm using defines so I don't have to calculate all the branches manually. If I remember correctly this worked just fine with Hackmew's assembler, which uses DevkitARM.

Red John

Progressing Assembly hacker

Male
Where ever there is peace and darkness
Seen May 31st, 2018
Posted September 25th, 2015
137 posts
9 Years
I have a few questions. Is it possible to show a background via ASM? And if it is, could anyone explain to me how to use it (the routine location, parameters)? Or is it done via multiple routines instead of one routine?

C me

Creator of Pokemon League Of Legends

Age 26
Male
Seen April 9th, 2021
Posted September 9th, 2018
681 posts
9.3 Years
The 'flymap' routine is at 0x0C4EF8 in FireRed so callasm 0x0C4EF9 shows you the flymap. (FBI found this, not me)

I've been trying to find the Emerald equivalent for the past few hours looking through a hex editor searching for a string of bytes from the routine in FireRed that might lead me to the one in Emerald.

But so far nothing...

Anyone know another way of finding it, or anyone know where it is?
Check out my hack: Pokemon League of Legends.
Join the subreddit: https://www.reddit.com/r/PokemonLoL/
If you would like to give me money for no reason you can do so here
Seen November 20th, 2016
Posted November 20th, 2016
417 posts
8.2 Years
The 'flymap' routine is at 0x0C4EF8 in FireRed so callasm 0x0C4EF9 shows you the flymap. (FBI found this, not me)

I've been trying to find the Emerald equivalent for the past few hours looking through a hex editor searching for a string of bytes from the routine in FireRed that might lead me to the one in Emerald.

But so far nothing...

Anyone know another way of finding it, or anyone know where it is?
Using a hex editor to look for exact bytes won't work; it surely uses bl instructions at various places within the routine even if it miraculously uses the "same" routine (which it probably doesn't given that emerald has only one map). Is there anything you know about the fly map? I would use something that you "know" to set a break on read with vba-sdl-h and follow the routine from there.

C me

Creator of Pokemon League Of Legends

Age 26
Male
Seen April 9th, 2021
Posted September 9th, 2018
681 posts
9.3 Years
Using a hex editor to look for exact bytes won't work; it surely uses bl instructions at various places within the routine even if it miraculously uses the "same" routine (which it probably doesn't given that emerald has only one map). Is there anything you know about the fly map? I would use something that you "know" to set a break on read with vba-sdl-h and follow the routine from there.
Oh yeah I forgot about the other maps. The method worked for surf I thought it would work for fly too.

I guess what I 'know' is the tileset/tilemap location, the flags needed to fly to each city and that doanimation,0E,0F and 20 do the flying animation.

Is that good enough or completely useless?
Check out my hack: Pokemon League of Legends.
Join the subreddit: https://www.reddit.com/r/PokemonLoL/
If you would like to give me money for no reason you can do so here

Blah

Free supporter

Male
Unknown Island
Seen 52 Minutes Ago
Posted February 28th, 2023
1,924 posts
10.3 Years
Oh yeah I forgot about the other maps. The method worked for surf I thought it would work for fly too.

I guess what I 'know' is the tileset/tilemap location, the flags needed to fly to each city and that doanimation,0E,0F and 20 do the flying animation.

Is that good enough or completely useless?
It should work. If someone has researched field moves in Emerald, there should be a table of routines for each move there too. Try finding it from that.
...

C me

Creator of Pokemon League Of Legends

Age 26
Male
Seen April 9th, 2021
Posted September 9th, 2018
681 posts
9.3 Years
It should work. If someone has researched field moves in Emerald, there should be a table of routines for each move there too. Try finding it from that.
They're in a table? That means I could go to the surf routine, find the pointer to it and fly will be near it right? I'll look into it tomorrow I'm off to bed now.
Check out my hack: Pokemon League of Legends.
Join the subreddit: https://www.reddit.com/r/PokemonLoL/
If you would like to give me money for no reason you can do so here

GoGoJJTech

(☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)

Age 24
Female
Earth
Seen December 9th, 2016
Posted December 5th, 2016
2,475 posts
10.5 Years
If r0 held a pointer(let's just say I'm using 0x20270B6 as an example), would r1 hold that pointer as well if I did ldr r1, [r0]?
It would not. What that'd do is load the word at r0's location into r1. That's what the [] is for.
I believe in Jesus Christ my Savior. If you do too, and aren't scared to admit it, then copy and paste this into your signature.
The HGSS Music Patch - The BW/2 Music Patch - ASM: Switch Music Based on Seasons
Romhack.me Profile - Pokecommunity Profile - Youtube Channel

Support me at my site!
Pokémon Platinum Red and Blue