Advertiser Content

Help Thread ASM & Disassembly

Started by Spherical Ice December 1st, 2014 11:05 AM
  • 53961 views
  • 626 replies

Spherical Ice

Age 21
Bristol, UK
Seen 3 Hours Ago
Posted 3 Weeks Ago
5,254 posts
11.9 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.

Percy

Male
Asia
Seen 16 Hours Ago
Posted 22 Hours Ago
2,969 posts
5.1 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

Age 19
Male
Seen May 6th, 2019
Posted March 11th, 2017
1,070 posts
6.4 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?
If you inserted a routine at 0x800000, in the script you would put callasm 0x800001.

Red John

Progressing Assembly hacker

Male
Where ever there is peace and darkness
Seen May 31st, 2018
Posted September 25th, 2015
137 posts
5.5 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?
Not all routines need that, but most of them do. Routines made in thumb mode requires the +1 in order to execute it properly. Hope this helped.

DarkenedEclipse

Project Oak

Male
Sinnoh
Seen December 24th, 2016
Posted October 2nd, 2015
207 posts
5.3 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

esperance

Age 22
Male
Ohio
Seen 1 Day Ago
Posted June 23rd, 2019
3,827 posts
9.6 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
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).
What are you so afraid of?

Lance32497

LanceKoijer of Pokemon_Addicts

Male
Criscanto town-Ginoa Region xD
Seen August 13th, 2017
Posted January 1st, 2017
793 posts
5.2 Years
Does anyone here has Karatekids ASM COMPILER tool?
The Download link in his thread is broken link.
This signature has been disabled.
Scrollbar appears
Please review and fix the issues by reading the signature rules.

You must edit it to meet the limits set by the rules before you may remove the [sig-reason] code from your signature. Removing this tag will re-enable it.

Do not remove the tag until you fix the issues in your signature. You may be infracted for removing this tag if you do not fix the specified issues. Do not use this tag for decoration purposes.

Danny0317

Fluorite's back, brah

Age 19
Male
Seen May 6th, 2019
Posted March 11th, 2017
1,070 posts
6.4 Years
Does anyone here has Karatekids ASM COMPILER tool?
The Download link in his thread is broken link.
After some quick googling...

http://pokemonhackersonline.com/showthread.php?t=14514-THUMB-Editor-Assembler

Download there works.

Lance32497

LanceKoijer of Pokemon_Addicts

Male
Criscanto town-Ginoa Region xD
Seen August 13th, 2017
Posted January 1st, 2017
793 posts
5.2 Years
After some quick googling...

http://pokemonhackersonline.com/showthread.php?t=14514-THUMB-Editor-Assembler

Download there works.
o.O I did looked at that link but It contains the link here in PC!
Whoah! Thanks Man!
Ahahahahahhahaha
When I tested it...
It was the tool that I used before xD
Thanks

BLAx501!

Pokemon Flux

Male
Madrid, Spain
Seen 2 Days Ago
Posted February 5th, 2019
80 posts
6 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:
.thumb
.align 2
push {lr}
ldr r0, SCRIPT_ADRESS
bl SCRIPT_ROUTINE  @Subroutine that executes the script
pop {pc}

SCRIPT_ROUTINE:
ldr r1, SCRIPT_EXECUTER
Bx r1

.align 2
SCRIPT_ADRESS: .word 0x081624F5  @Script offset
SCRIPT_EXECUTER: .word 0x08069AE5  @Offset of the routine that executes the script


And my script was this one:
Spoiler:
#dynamic 0x800000
#org @start
lock
if 0x1 goto @call
addvar 0x4011 0x1
release
end

#org @call
msgbox @ring 0x6
release
end

#org @ring
= This is just a test.


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:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r2}
	ldr r0, .Counters
	ldrb r1, [r0]
	cmp r1, #0xFF
	beq increment
	add r1, r1, #0x1
	strb r1, [r0]
	b end

increment:
	mov r1, r0
	add r1, #0x1
	ldrh r2, [r1]
	add r2, #0x1
	strh r2, [r1]
	mov r2, #0x0
	strb r2, [r0]

end:
	pop {r0-r2}
	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
	
	
.align 2

.Counters:
	.word 0x203BFFD @location to store exp counters


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:
.text
.align 2
.thumb
.thumb_func

main:
push {r0-r4, lr}
ldr r3, .Script_Adress
ldr r0, .Counters
ldrb r1, [r0]
cmp r1, #0xFF
beq increment
add r1, r1, #0x1
strb r1, [r0]
b end
bl Script_Routine @Subroutine that executes the script

increment:
mov r1, r0
add r1, #0x1
ldrh r2, [r1]
add r2, #0x1
strh r2, [r1]
mov r2, #0x0
strb r2, [r0]

end:
pop {r0-r2}
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, #0x1
beq linker
mov r0, r5
ldr r1, =(0x806D600 +1)
bx r1
pop {pc}

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

Script_Routine:
ldr r4, .Script_Executer
Bx r4


.align 2

.Counters:
.word 0x203BFFD @location to store exp counters
.Script_Adress:
.word 0x081624F5 @Script adress
.Script_Executer:
.word 0x08069AE5 @Offset of the routine that executes the script





I'll accept all possible help xD

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 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:
.text
.align 2
.thumb
.thumb_func

main:
push {r0-r4, lr}
ldr r3, .Script_Adress
ldr r0, .Counters
ldrb r1, [r0]
cmp r1, #0xFF
beq increment
add r1, r1, #0x1
strb r1, [r0]
b end
bl Script_Routine @Subroutine that executes the script

increment:
mov r1, r0
add r1, #0x1
ldrh r2, [r1]
add r2, #0x1
strh r2, [r1]
mov r2, #0x0
strb r2, [r0]

end:
pop {r0-r2}
lsl r0, r0, #0x18
lsr r0, r0, #0x18
cmp r0, #0x1
beq linker
mov r0, r5
ldr r1, =(0x806D600 +1)
bx r1
pop {pc}

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

Script_Routine:
ldr r4, .Script_Executer
Bx r4


.align 2

.Counters:
.word 0x203BFFD @location to store exp counters
.Script_Adress:
.word 0x081624F5 @Script adress
.Script_Executer:
.word 0x08069AE5 @Offset of the routine that executes the script





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:

.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:

.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

Male
Madrid, Spain
Seen 2 Days Ago
Posted February 5th, 2019
80 posts
6 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

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 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

Male
Madrid, Spain
Seen 2 Days Ago
Posted February 5th, 2019
80 posts
6 Years
It worked :D

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

Here's the final routine:

.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

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 Years
It worked :D

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

Here's the final routine:

.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
...

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 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%C3%A9mon_data_structure_in_Generation_III
...

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 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 :)
...
Seen 6 Hours Ago
Posted August 27th, 2019
770 posts
12.6 Years
What's the most idiomatic way to clear all but the least significant byte from a register?

I currently have two thoughts:

lsl r1, r1, #0x18
lsr r1, r1, #0x18
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?

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 Years
What's the most idiomatic way to clear all but the least significant byte from a register?

I currently have two thoughts:

lsl r1, r1, #0x18
lsr r1, r1, #0x18
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?
For the first one, you're losing the significant byte.
You've got the shifts backwards. Clearing the last byte would be done like this:

lsr r0, r0, #0x8
lsl r0, r0, #0x8
Say you have FFFF. Shifting it right 8 bits (1 byte) gives you 0FFF, then you shift it left 8 more bits to get FFF0 :)
...
Seen 6 Hours Ago
Posted August 27th, 2019
770 posts
12.6 Years
For the first one, you're losing the significant byte.
You've got the shifts backwards. Clearing the last byte would be done like this:

lsr r0, r0, #0x8
lsl r0, r0, #0x8
Say you have FFFF. Shifting it right 8 bits (1 byte) gives you 0FFF, then you shift it left 8 more bits to get FFF0 :)
Sorry, I may have been a little unclear. I'm trying to get clear all but the least significant byte. As in, if you have FFFF, you shift up to F000, and then back down to 000F.

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 Years
Sorry, I may have been a little unclear. I'm trying to get clear all but the least significant byte. As in, if you have FFFF, you shift up to F000, and then back down to 000F.
Oh, looks like I've read incorrectly. Yeah, shifting would be faster and better.
...
Male
California
Seen May 3rd, 2016
Posted December 22nd, 2015
51 posts
6.2 Years
A friend shared with me this script to check a pokemon's ability:
ldrb r0, [08XXXXXX] (=$02023D6B) offsetof the Pokémon attacking
mov r1, #0x58
mul r0, r1
ldr r1, [08XXXXXX] (=$02023BE4)Offset for all of the 4 Pokémon's datas each Pokémon takes 58 bytes of data according to bulbapedia
add r1, r1, r0
add r1, r1, #0x20
ldrb r1, [r1]
cmp r1, #0x? with the ? as the ability I want to check
Now I do various things based on what the ability is correct? How and where do I place this within the ROM? I am just having trouble in general finding where I am supposed to put my scripts in general so that the game checks for it without replacing existing code
~Eclectic~

FBI

Free supporter

Male
Unknown Island
Seen 1 Day Ago
Posted March 30th, 2019
1,905 posts
6.7 Years
A friend shared with me this script to check a pokemon's ability:
ldrb r0, [08XXXXXX] (=$02023D6B) offsetof the Pokémon attacking
mov r1, #0x58
mul r0, r1
ldr r1, [08XXXXXX] (=$02023BE4)Offset for all of the 4 Pokémon's datas each Pokémon takes 58 bytes of data according to bulbapedia
add r1, r1, r0
add r1, r1, #0x20
ldrb r1, [r1]
cmp r1, #0x? with the ? as the ability I want to check
Now I do various things based on what the ability is correct? How and where do I place this within the ROM? I am just having trouble in general finding where I am supposed to put my scripts in general so that the game checks for it without replacing existing code
This is probably not what you're looking for. Those offsets are for battle data. In the battle it records various things about each combatant and one of the things happens to be ability.

If you just want to check the Pokemon's ability in overworld it would be different. You'd use the Pokemon decrypter to figure out which ability bit is turned on and depending on that, you would need to use the Pokemon Base stats table to search for which ability it currently has. Then, finally link the ability number to a string.

I just wrote a routine that happens to do all that for you: http://www.pokecommunity.com/showpost.php?p=8533783&postcount=280
...
Advertiser Content