• 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
    • Seen yesterday
    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