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

Bonnox

Time (wasting) Lord
47
Posts
8
Years
  • Hello, good morning/evening (depending on your locale)
    I am a recently signed up user and this forum is amazing!
    The only problem is that is a bit too large, so at the beginning is confusing, so may you forgive me if I post in the wrong thread (there is another "ASM thread" that counts dozen of pages, so wich is the correct one to post on? why isn't there a "questions" section? or maybe we just have to put everything in one topic?).


    I am one of those crazy who are working on Ruby, and therefore I don't have a really full documentation of the game, actually a lot of parts are obscure.
    I would lie if didn't tell that I learned the principles of ASM thanks to this forum, and now I can write and read it quite well. But obviously I'm not a pro yet, because there are a several things that I still dont't understand.

    One of them is a feature I was thinking about that would be really cool if it was implemented. The idea was given me by an user, and is, in a nutshell, to create some "overlay" of information displayed without using the BG0 to write, but instead of it the OAM; in short terms, an HUD. He actually succeeded in it, while I'm constantly facing huge issues because of my poor, (almost) abandoned platform of choice.

    So the question is: which is the routine to call to add an Object to the game during the "overworld" ?
    In the past I just tried WBTO-ing the data, but they are literally obliterated during the next cycle of the game (which, indeed, happens really soon)!
    So I thought it was working like the palettes, and searched for the entries anywhere in the RAM... with no acceptable risulta only the player oam data seems tuo be replicated. Sooo, the structure of a buffer might have been really more complicated than I had thought...
    Then I tried putting some breakpoints with VBA-SDL, and that also did't end well... basically it is called too often, ad is a lonely

    SWI
    BX

    isolated in the middle offerte nowhere the ROM... Where the hell is it called from then?!?!

    I also tried searching though the topics with the tools of the forum, but with poor results.

    Now I quite have ran out of options, and YouTube could be my save, yet the Last hope.
    Do you know how to set up a fully working OAM during the normal gameplay? (obviously I am able to do it in an ASM/C routine wich takes the full control over the hardware)

    thanks to everybody that will have pity of me and routes me towards the good direction!

    have a nice day! :)
     
    Last edited:
    325
    Posts
    10
    Years
  • A couple of questions about ASM.
    How does divmod2 work? I know that it'll divide using r0 as the numerator and r1 as the denominator, but where does the remainder go?
    What does the 'and' and 'or' commands do? I can't find a comprehensive guide to those two commands, so when I see them in a disassembly I get lost.
    Does the stack pointer store words for each register pushed? For example, if I wrote push {r0, lr}, there'd be 8 bytes (a word for each) stored wherever the stack pointer is, correct?
     
    5,256
    Posts
    16
    Years
  • A couple of questions about ASM.
    How does divmod2 work? I know that it'll divide using r0 as the numerator and r1 as the denominator, but where does the remainder go?
    What does the 'and' and 'or' commands do? I can't find a comprehensive guide to those two commands, so when I see them in a disassembly I get lost.
    Does the stack pointer store words for each register pushed? For example, if I wrote push {r0, lr}, there'd be 8 bytes (a word for each) stored wherever the stack pointer is, correct?

    DivMod1 returns the integer, DivMod2 returns the remainder. Both return the result to r0.

    DivMod1 (Takes in R0 as Numerator and R1 as Denominator; Returns INTEGER DIVISION (9/2 = 4 r 1) result to R0): 0x1E4018
    DivMod2 (Takes in R0 as Numerator and R1 as Denominator; Returns REMAINDER OF INTEGER DIVISION (23/4 = 5 r 3 to R0): 0x1E4684

    (from here)

    AND, OR, XOR, etc. are logic gates. I'd recommend just googling that, it's a pretty important programming concept. They're similar to operations like addition and subtraction, but work specifically for binary numbers. Here's a random document I found on it.

    I'm not too clear on the stack myself, but I'd recommend looking in an IDB to see how pushing the link register and returning from bls works in vanilla.
     
    325
    Posts
    10
    Years
  • DivMod1 returns the integer, DivMod2 returns the remainder. Both return the result to r0.



    AND, OR, XOR, etc. are logic gates. I'd recommend just googling that, it's a pretty important programming concept. They're similar to operations like addition and subtraction, but work specifically for binary numbers. Here's a random document I found on it.

    I'm not too clear on the stack myself, but I'd recommend looking in an IDB to see how pushing the link register and returning from bls works in vanilla.
    Ah, I see, thank you.


    Ok, I'll read that in my free time.


    I looked at Touched's ASM tutorial again, and it does store/load words each time.
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • To expand on what Spherical Ice has said, it might not be immediately intuitive that the logic gates here are working as bitwise XoR, AND and OR.

    For example:
    (0x9 OR 0x16 = 0x1F)

    mov r0, #0x9
    mov r1, #0x16
    orr r0, r0, r1

    Converting these values to binary we see:
    01001 OR 10110 = 11111
    --

    A good example of this is when the game generates a 32bit random number for a Pokemon's PID. The Pseudo random number generator in Gen III is only capable of generating 16 bit values, so it cleverly uses some logic and bitshifting to generate the PID. Similar to this:

    Code:
    bl rand
    lsl r0, r0, #0x10
    mov r4, r0
    bl rand
    lsr r0, r0, #0x10
    orr r0, r0, r4

    A related topic which I think may interest you is flags which are raised during certain instructions. It allows for more efficient code and sometimes can allow you to avoid certain logic operations.

    Does the stack pointer store words for each register pushed? For example, if I wrote push {r0, lr}, there'd be 8 bytes (a word for each) stored wherever the stack pointer is, correct?
    So generally the SP is in R13. The stack is just like an area in RAM and when you push or pop registers the SP either decreases or increases (usually by 4) depending on if you pushed or popped. In any case, the stack pointer is just a pointer to the current "index" of the stack. The stack itself isn't dynamic memory, it's a static amount of memory which is set aside from the start, so by pushing two registers, you've essentially moved/decreased the SP by 8 bytes and stored the values of the registers.

    Fetching these pushed registers are normally done by simply using the pop instruction. In larger routines, you may see a case where medium registers are pushed and high registers are backed up into the medium registers. Ingeneral, we don't fetch the values of pushed registers by directly accessing the stack memory. If you find yourself needing to do that, then the design of your code needs to change :O
     
    417
    Posts
    9
    Years
    • Seen Nov 20, 2016
    A couple of questions about ASM.
    How does divmod2 work? I know that it'll divide using r0 as the numerator and r1 as the denominator, but where does the remainder go?
    What does the 'and' and 'or' commands do? I can't find a comprehensive guide to those two commands, so when I see them in a disassembly I get lost.
    Does the stack pointer store words for each register pushed? For example, if I wrote push {r0, lr}, there'd be 8 bytes (a word for each) stored wherever the stack pointer is, correct?
    I'm guessing you understand and miswrote it, but just the be clear. The stack pointer does not store any words that were in the pushed registers. The stack contains the contents of those registers. The stack pointer contains a pointer to the most recent word pushed. A lot of people describe the stack as a literal stack. It's a fine explanation, but I have an easier time thinking about it as a plain old hex file that I'm editing, one word at a time. Don't think of the stack as anything magical. (I) think of it as a chunk of RAM that is constantly being edited.

    Let's say the stack pointer begins at 0x038000000. I do a bl to a subroutine.
    The subroutine begins push {r4-r7, lr}.
    When you push/pop multiple registers, it is assumed that the highest register is pushed to or popped from the highest address in the stack.
    So if we began
    r4=abra
    r5=bulbasaur
    r5=caterpie
    r6=dragonite
    r7=electabuzz
    lr=flareon
    After push {r4-r7, lr} we have
    0x037FFFFC: flareon
    0x037FFFF8: electabuzz
    0x037FFFF4: dragonite
    0x037FFFF0: caterpie
    0x037FFFEC: bulbasaur
    0x037FFFE8: abra
    And as a result of the push, the stack pointer is updated to 0x037FFFE8.

    Then, the routine typically ends
    {pop r4-r7}
    {pop r0} or {pop r1} depending on whether a return exists
    bx r0/r1

    So after pop {r4-r7}, the contents of r4-r7 are again restored
    r4=abra
    r5=bulbasaur
    r5=caterpie
    r6=dragonite
    r7=electabuzz
    & the stack pointer contains the address 0x037FFFFC.

    Then, pop {r0/r1} to get the value that was initially stored in the link register (for a return address}
    & the stack pointer once again contains the address 0x038000000.

    I don't know if any of that helped.

    Edit: ninjad :(
     
    41
    Posts
    10
    Years
  • How to compile and use this patch? (it is for gold)

    Spoiler:


    Also, PKSVUI cant load Scintilla.dll even though they're in the same directory

    BUMP -- how to hack golds rtc with asm
     
    Last edited by a moderator:

    Kimonas

    %string not found
    91
    Posts
    13
    Years
  • short question that buffles me:

    ldr r1, some_address
    ldr r1, [r1]

    lsl r1, #0x8
    lsr r0, r1, #0x8

    So, after the last line is executed r0 will have the value of r1 shifted right 8 times (actually it will have the original value of r1, but with its first byte cleaned).

    Now, my question is: in the last line when it shifts r1 right, does it also change r1, so both r1 and r0 have the same value in the end? Or r1 sticks with the value it had in the previous line?
     

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • short question that buffles me:

    ldr r1, some_address
    ldr r1, [r1]

    lsl r1, #0x8
    lsr r0, r1, #0x8

    So, after the last line is executed r0 will have the value of r1 shifted right 8 times (actually it will have the original value of r1, but with its first byte cleaned).

    Now, my question is: in the last line when it shifts r1 right, does it also change r1, so both r1 and r0 have the same value in the end? Or r1 sticks with the value it had in the previous line?

    r1 is unchanged in the last line. So r0 and r1 have different values.
     
    417
    Posts
    9
    Years
    • Seen Nov 20, 2016
    short question that buffles me:

    ldr r1, some_address
    ldr r1, [r1]

    lsl r1, #0x8
    lsr r0, r1, #0x8

    So, after the last line is executed r0 will have the value of r1 shifted right 8 times (actually it will have the original value of r1, but with its first byte cleaned).

    Now, my question is: in the last line when it shifts r1 right, does it also change r1, so both r1 and r0 have the same value in the end? Or r1 sticks with the value it had in the previous line?
    "First byte" is a bit ambiguous. If I heard "first byte," I would think of the LEAST significant byte, but the byte that is cleared is actually the MOST significant byte.
    If after ldr r1, [r1], r1 contained:
    0xDDCCBBAA
    You'd have
    lsl r1, #0x8
    which would make r1 contain: 0xCCBBAA00
    Then after lsr r0, r1, #0x8
    r0 would contain: 0x00CCBBAA

    With that cleared up, to answer your question, r1 is not changed in the last line.
    It will still contain 0xCCBBAA00

    EDIT: ninja'd. Again. I should just stop posting in this thread :(
     

    Kimonas

    %string not found
    91
    Posts
    13
    Years
  • "First byte" is a bit ambiguous. If I heard "first byte," I would think of the LEAST significant byte, but the byte that is cleared is actually the MOST significant byte.
    If after ldr r1, [r1], r1 contained:
    0xDDCCBBAA
    You'd have
    lsl r1, #0x8
    which would make r1 contain: 0xCCBBAA00
    Then after lsr r0, r1, #0x8
    r0 would contain: 0x00CCBBAA

    With that cleared up, to answer your question, r1 is not changed in the last line.
    It will still contain 0xCCBBAA00

    EDIT: ninja'd. Again. I should just stop posting in this thread :(

    Oh, that was what I meant, but thank you for clarifying me that :)
     

    C me

    Creator of Pokemon League Of Legends
    681
    Posts
    10
    Years
    • Seen Apr 9, 2021
    If you replace a move effect routine with callasm the offset of that routine +1 why does it cause the game to freeze? I thought effect commands were just built in callasms.

    I want to be able to splice the 2 effects of endure and recover so that if you survive a hit with endure you regain some hp.

    I thought I could just add a hook around where the 'endured the hit' text pointer is to the heal routine but if I can't even callasm it in a battle script, it won't work. Am I just doing it wrong?

    Endure routine:
    Spoiler:


    Recover routine:
    Spoiler:
     
    417
    Posts
    9
    Years
    • Seen Nov 20, 2016
    If you replace a move effect routine with callasm the offset of that routine +1 why does it cause the game to freeze? I thought effect commands were just built in callasms.

    I want to be able to splice the 2 effects of endure and recover so that if you survive a hit with endure you regain some hp.

    I thought I could just add a hook around where the 'endured the hit' text pointer is to the heal routine but if I can't even callasm it in a battle script, it won't work. Am I just doing it wrong?

    Endure routine:
    Spoiler:


    Recover routine:
    Spoiler:
    I don't know if you phrased that incorrectly. But don't replace a routine with callasm, which is script. You need to branch to the routine with asm, or use callasm within a battle script.
    If that isn't the problem, please post your actual routines. I don't think anyone reads THUMB in hex :P
     

    C me

    Creator of Pokemon League Of Legends
    681
    Posts
    10
    Years
    • Seen Apr 9, 2021
    I don't know if you phrased that incorrectly. But don't replace a routine with callasm, which is script. You need to branch to the routine with asm, or use callasm within a battle script.
    If that isn't the problem, please post your actual routines. I don't think anyone reads THUMB in hex :P

    I meant using callasm in a battle script to the routine should work the same as using that command.

    For example in bsp you would use 'ppreduce' which in hex is command 03. What command 03 does comes from a table of command routines, the third being the pointer to the ppreduce routine (not actually changing ppreduce btw, just an example).

    So why does callasming that routine not have the same effect as using the command in bsp, ie why does F9 xx xx xx 08 not have the same effect as 03 if they both point to the same routine.(F9 is callasm in my hack)

    Or maybe they do and I just did it wrong.

    They're not my routines, they're the vanilla Emerald ones so sorry I only have the hex.
     

    Kimonas

    %string not found
    91
    Posts
    13
    Years
  • In knizz's database I see functions like flag_set/clear and var_set which I'm guessing XSE is also using from the same addresses(?). If this is what's happening is there a list or a way to find the addresses of the other functions used by XSE, like applymovement or msgbox?

    ~~~Edit~~~

    Nvm, just found out. It's explained here,thank you Spherical Ice :).

    Question: Why every script commands runs the script_read_word in the beginning? Also, what exactly is the script_env struct?
     
    Last edited:

    Blah

    Free supporter
    1,924
    Posts
    11
    Years
  • In knizz's database I see functions like flag_set/clear and var_set which I'm guessing XSE is also using from the same addresses(?). If this is what's happening is there a list or a way to find the addresses of the other functions used by XSE, like applymovement or msgbox?

    ~~~Edit~~~

    Nvm, just found out. It's explained here,thank you Spherical Ice :).

    Question: Why every script commands runs the script_read_word in the beginning? Also, what exactly is the script_env struct?

    No, they're not the same. The script engine does the interpreting and then calls a script function from it's library depending on the command. If the command has an argument, the argument is read by the command using script_read_word ect. You can find the exact structure for the script environment in IDA, though it also has a few useful byes outside of that structure in RAM.
     

    Mechakhan

    OH NOES! A VIRUS HAS BEEN DETECECETD!
    31
    Posts
    9
    Years
  • Hi! I've been trying to insert a double battle in Pokémon FireRed. (Like the one in Emerald with Steven.)
    I tried to debug the routine for Special 0xEF (Steven battle) with VBA-SDL-H, but my knowledge of Emerald memory addresses is pretty lacking, so I didn't understand much of what the routine did. I couldn't find much by googling either.

    I also tried to modify the Link Multi Battle script in FireRed with XSE, but that didn't lead anywhere either, which is probably because Special 0x20 in FireRed requires Link data?

    If anyone has an idea of what I could try, I would really appreciate it. Is it possible to modify the link data via ASM? If so, what offsets should be changed? I am by no means asking for an ASM routine, just a tip so I can solve it myself. ;)
     
    417
    Posts
    9
    Years
    • Seen Nov 20, 2016
    Hi! I've been trying to insert a double battle in Pokémon FireRed. (Like the one in Emerald with Steven.)
    I tried to debug the routine for Special 0xEF (Steven battle) with VBA-SDL-H, but my knowledge of Emerald memory addresses is pretty lacking, so I didn't understand much of what the routine did. I couldn't find much by googling either.

    I also tried to modify the Link Multi Battle script in FireRed with XSE, but that didn't lead anywhere either, which is probably because Special 0x20 in FireRed requires Link data?

    If anyone has an idea of what I could try, I would really appreciate it. Is it possible to modify the link data via ASM? If so, what offsets should be changed? I am by no means asking for an ASM routine, just a tip so I can solve it myself. ;)
    I don't believe it has ever been done. If you really care about it, it would actually be one of the biggest reasons to hack Emerald. There is zero chance you're going to do this with XSE. I would recommend taking a look at an Emerald IDB to get an understanding of important Emerald RAM locations, but in general, there's a lot less documentation on Emerald.
     
    Status
    Not open for further replies.
    Back
    Top