• Our software update is now concluded. You will need to reset your password to log in. In order to do this, you will have to click "Log in" in the top right corner and then "Forgot your password?".
  • Welcome to PokéCommunity! Register now and join one of the best fan communities on the 'net to talk Pokémon and more! We are not affiliated with The Pokémon Company or Nintendo.

Help Thread: ASM & Disassembly

Status
Not open for further replies.
5,256
Posts
16
Years

ASM & Disassembly Help Thread

This thread is for any questions related to disassembly, assembly and routine-related work that may arise when hacking. Post here with your problem, embedding lengthier excerpts of code in [SPOILER]spoiler tags[/SPOILER] for readability. Be sure to clearly and thoroughly describe your problem, including what ROM(s) the problem relates to and what exactly you are stuck with. This is NOT an assembly request thread!

Thread rules

Do not demand for answers to your questions!
People to not have to answer your questions, they do it because they want to! Not only are those posts annoying, they also are completely pointless! If such a post is found, it will probably be deleted.

This is NOT an assembly request thread!
This needs reiterating: this thread is not for asking people to make routines for you, nor is it for suggesting ideas of new features that require ASM.

When answering, quote the post with the question.
This is here to simply keep organization. It is much easier to read the thread when you have both the question and the answer. The users quoted will also get a notification so they will know their question has been replied to.
 
Last edited by a moderator:
3,044
Posts
9
Years
Yay, a new thread!

Anyway, I can't understand the thing when you insert ASM that you need the "+1"

What does that mean, and how to do that?
 

Danny0317

Fluorite's back, brah
1,067
Posts
10
Years
  • Age 24
  • Seen Nov 19, 2023
Yay, a new thread!

Anyway, I can't understand the thing when you insert ASM that you need the "+1"

What does that mean, and how to do that?

If you inserted a routine at 0x800000, in the script you would put callasm 0x800001.
 

DarkenedEclipse

Project Oak
207
Posts
9
Years
Question of clarification as I'm just starting to learn lol:
1. Register's data is determined by the pushed registries?
2. What are some of the variables like .VAR and what do they mean? How are they defined?
3. An ASM routine retrieves certain data from the ROM's RAM?
4. Once the data is popped the routine is done?

Sorry if these are simple questions, I am very new to this lol and I got a lot of questions XD
 
3,830
Posts
14
Years
  • Age 27
  • OH
  • Seen Feb 26, 2024
Question of clarification as I'm just starting to learn lol:
1. Register's data is determined by the pushed registries?
2. What are some of the variables like .VAR and what do they mean? How are they defined?
3. An ASM routine retrieves certain data from the ROM's RAM?
4. Once the data is popped the routine is done?

Sorry if these are simple questions, I am very new to this lol and I got a lot of questions XD

1. There are many different ways to set the data for a specific register, however using the push command is not one of them. The push command stores the value of a given register in a memory structure called the stack, so that it you need to use the register for something else, it is saved for later.

2. The only variables you have in ASM are the registers. What you are talking about are labels, which can be essentially be any character (A-Z,a-z,0-9,_,.) as long as it ends in a ":". These are used by the assembler as points of reference for when code needs to jump to a certain location or read data from a certain point. I am assuming when you saw the .var, the next line was started with ".word" followed by a number. This means that when you reference that label (.var), you are telling the code to go to the data stored at that location in the ROM.

3. Sometimes. An ASM routine is the code that makes up a ROM, and tells the GBA/emulator what to do. Everything that happens in the game starts with the ASM code. This means for the most part reading and writing to the RAM, and most of the time when we make routines it is so we can access the memory in a new way.

4. A subroutine ends not when the data is popped. Using the pop command merely means to tell the stack to remove the last few pieces of data and put them into the registers we want. A subroutine will typically end when you return to the location from which the routine was originally called (which can be done a couple of different ways).
 

BLAx501!

Pokemon Flux
80
Posts
10
Years
Hello everyone, I'm trying to run a script every step the player does, but I'm not good enough on ASM to do it all on my own.

First of all, I needed the way to run scripts by ASM, so I found a routine written by Sonicarvallho that allows you to run a script:
Spoiler:

And my script was this one:
Spoiler:

What it is suposed to do is to do addvar 0x4011 0x1 every step, and if the value becomes A (in ths example) show the message.

FBI Agent told me that his Exp Gain routine was executed every single step so now is where my doubt comes...

This is FBI routine:

Spoiler:

How can I modify that routine in order to make mine work??

I've done this, but I'm not sure if it's correct... I'll put on BOLD my changes

Spoiler:


I'll accept all possible help xD
 

Blah

Free supporter
1,924
Posts
11
Years
Hello everyone, I'm trying to run a script every step the player does, but I'm not good enough on ASM to do it all on my own.

...RANT...

How can I modify that routine in order to make mine work??

I've done this, but I'm not sure if it's correct... I'll put on BOLD my changes

Spoiler:


I'll accept all possible help xD

Wow, there's a lot going on here and most of it is wrong :P
First of all, my routine doesn't push the link register, because I directly jump back to where I hooked from. So there's really no need to push it. The routine you showed before for executing a script is done rather poorly. I would do it like this:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	ldr r0, .SCRIPT_ADDRESS
	ldr r1, =(0x8069AE4 +1)
	bl linkerTwo
	pop {r0-r1, pc}

linkerTwo:
	bx r1
	
	
.align 2

.SCRIPT_ADDRESS:
	.word 0x8[script_location +1]

Quite simple! Though there's more here. We don't want to mess around with the link register or program counter here because we simply don't need to, lol.

If you were to combine these two routines, you wouldn't push the link register because we're hooking from the middle of an existing function. Instead bx lr, we'll just bx directly to the address. I have not tested the routine which you've shown me about executing scripts, so I'm not sure if that is correct.
Here's a routine that combines the two:

Code:
.text
.align 2
.thumb
.thumb_func

main:
        @if this code crashes change r3 to r7
	push {r0-r3}
	ldr r0, .SCRIPT_ADDRESS
	ldr r1, =(0x8069AE4 +1)
	bl linkerTwo

end:
        @if this code crashes change r3 to r7
	pop {r0-r3}
	lsl r0, r0, #0x18
	lsr r0, r0, #0x18
	cmp r0, #0x1
	beq linker
	mov r0, r5
	ldr r1, =(0x806D600 +1)
	bx r1

linker:
	ldr r0, =(0x806D650 +1)
	bx r0

linkerTwo:
	bx r1
	
	
.align 2

.SCRIPT_ADDRESS:
	.word 0x8[script_location +1]

This will run the routine 0x8069AE4 with your script as a paramater every step, and preserve the existing step-run routine. If this crashes there are two causes:
1) you messed up inserting it/SCRIPT_ADDRESS pointer is wrong
2) the routine at 0x8069AE4 doesn't work like you think it works
3) look at the comments in my routine (though the first two are probably the cause)

Hopefully it will work right away :P
 

BLAx501!

Pokemon Flux
80
Posts
10
Years
This will run the routine 0x8069AE4 with your script as a paramater every step, and preserve the existing step-run routine. If this crashes there are two causes:
1) you messed up inserting it/SCRIPT_ADDRESS pointer is wrong
2) the routine at 0x8069AE4 doesn't work like you think it works
3) look at the comments in my routine (though the first two are probably the cause)

Hopefully it will work right away :P

I was 99% sure it was going to be wrong xD, but theres always a slight possibility xD.

So to test this I should do the same HEX change you say on the ASM Resource Thread isn't it? To make it work along with the existing routine
 

Blah

Free supporter
1,924
Posts
11
Years
I was 99% sure it was going to be wrong xD, but theres always a slight possibility xD.

So to test this I should do the same HEX change you say on the ASM Resource Thread isn't it? To make it work along with the existing routine

Yeah, the same hex change at the existing routine.
 

BLAx501!

Pokemon Flux
80
Posts
10
Years
It worked :D

But I had to make some changes to make it work properly xD.

Here's the final routine:

Code:
.text
.align 2
.thumb
.thumb_func

main:
        @if this code crashes change r3 to r7
	push {r0-r3}
	ldr r0, .SCRIPT_ADDRESS
	bl linkerTwo

end:
        @if this code crashes change r3 to r7
	pop {r0-r3}
	lsl r0, r0, #0x18
	lsr r0, r0, #0x18
	cmp r0, #0x1
	beq linker
	mov r0, r5
	ldr r1, =(0x806D600 +1)
	bx r1

linker:
	ldr r0, =(0x806D650 +1)
	bx r0

linkerTwo:
        ldr r1, .SCRIPT_EXECUTER
        bx r1
	
	
.align 2

.SCRIPT_ADDRESS:
	.word 0x0880025C
.SCRIPT_EXECUTER:
	.word 0x08069AE5

In fact, I'm not pretty sure if what I've done makes a difference from your code, but the point is that it works :D

Thank you a lot for your help, I love you man xD
 

Blah

Free supporter
1,924
Posts
11
Years
It worked :D

But I had to make some changes to make it work properly xD.

Here's the final routine:

Code:
.text
.align 2
.thumb
.thumb_func

main:
        @if this code crashes change r3 to r7
	push {r0-r3}
	ldr r0, .SCRIPT_ADDRESS
	bl linkerTwo

end:
        @if this code crashes change r3 to r7
	pop {r0-r3}
	lsl r0, r0, #0x18
	lsr r0, r0, #0x18
	cmp r0, #0x1
	beq linker
	mov r0, r5
	ldr r1, =(0x806D600 +1)
	bx r1

linker:
	ldr r0, =(0x806D650 +1)
	bx r0

linkerTwo:
        ldr r1, .SCRIPT_EXECUTER
        bx r1
	
	
.align 2

.SCRIPT_ADDRESS:
	.word 0x0880025C
.SCRIPT_EXECUTER:
	.word 0x08069AE5

In fact, I'm not pretty sure if what I've done makes a difference from your code, but the point is that it works :D

Thank you a lot for your help, I love you man xD
It does the exact same thing. I'm glad to hear that it worked anyways :P
 
10
Posts
9
Years
I'm making a Pokémon Emerald hack, and I'm learning ASM. But to make a asm I need the memory address to edit or access. How can i find these address (for exemple: your party Pokémon information).
 

Blah

Free supporter
1,924
Posts
11
Years
I'm making a Pokémon Emerald hack, and I'm learning ASM. But to make a asm I need the memory address to edit or access. How can i find these address (for exemple: your party Pokémon information).

I would use an idb. I think Touched has one for Emerald. To find addresses yourself is a little more work. Back when I did it by hand, I used to find related strings and back track over and over again using VBA's disassembler until I reached the routine I was looking for. All in all it's a painful process. As some daniilS likes to say, there's no need to re-invent the wheel.
Just look for other people's research and use it. Here's some bulbapedia stuff you'll find useful:
http://bulbapedia.bulbagarden.net/wiki/Pokémon_data_structure_in_Generation_III
 
10
Posts
9
Years
Thank you FBI by the links, now I want to know if exists a memory view for GBA that you can search a memory value, 'cause in no$gba and VBA i don't find this.
 

Blah

Free supporter
1,924
Posts
11
Years
Thank you FBI by the links, now I want to know if exists a memory view for GBA that you can search a memory value, 'cause in no$gba and VBA i don't find this.

You can use VBA's memory viewer to watch memory changes in real time. I combine this and VBA-SDL-H to search for specific memory bytes. Once you get used to swapping the two around, memory surfing is rather easy :)
 
788
Posts
17
Years
  • Age 29
  • Seen Apr 25, 2024
What's the most idiomatic way to clear all but the least significant byte from a register?

I currently have two thoughts:

Code:
lsl r1, r1, #0x18
lsr r1, r1, #0x18

Code:
mov r0, #0xFF
and r1, r0

I like the first because I don't have to use a second register, but the second is a bit clearer, and I'm guessing, faster. Which one should I go with? Or perhaps even a different alternative I haven't considered?
 
Status
Not open for further replies.
Back
Top