The PokéCommunity Forums  

Go Back   The PokéCommunity Forums > Fan Games > Binary ROM Hacking
Reload this Page Help Thread ASM & Disassembly

Notices
For all updates, view the main page.

Binary ROM Hacking Need a helping hand or just want to talk about binary ROM hacks? Get comments and answers to any ROM Hacking-related problems, questions or thoughts you have here.

Ad Content
Closed Thread
 
Thread Tools
  #326   Link to this post, but load the entire thread.  
Old June 7th, 2015 (8:56 PM).
Lance32497's Avatar
Lance32497 Lance32497 is offline
LanceKoijer of Pokemon_Addicts
 
Join Date: Aug 2014
Location: Criscanto town-Ginoa Region xD
Gender: Male
Nature: Adamant
Posts: 792
Hello guys, I'm trying to build a routine that lets the Var 8000 edit thePokémon data substructures(Bulbapedia term)
.... I had read the entire site but I can't find the RAM Address of that Pokemon Data substructure
__________________
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.
  #327   Link to this post, but load the entire thread.  
Old June 7th, 2015 (9:57 PM).
kleenexfeu kleenexfeu is offline
 
Join Date: Aug 2013
Gender: Male
Posts: 218
Quote:
Originally Posted by Lance32497 View Post
Hello guys, I'm trying to build a routine that lets the Var 8000 edit thePokémon data substructures(Bulbapedia term)
.... I had read the entire site but I can't find the RAM Address of that Pokemon Data substructure
Use the FBI's routine in the ASM resource thread. For the substructure it's wrote in bulbapedia, something like 0x020244EC for emerald if I remember well
  #328   Link to this post, but load the entire thread.  
Old June 7th, 2015 (10:27 PM).
Lance32497's Avatar
Lance32497 Lance32497 is offline
LanceKoijer of Pokemon_Addicts
 
Join Date: Aug 2014
Location: Criscanto town-Ginoa Region xD
Gender: Male
Nature: Adamant
Posts: 792
Quote:
Originally Posted by kleenexfeu View Post
Use the FBI's routine in the ASM resource thread. For the substructure it's wrote in bulbapedia, something like 0x020244EC for emerald if I remember well
Thanks, gonna check this
__________________
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.
  #329   Link to this post, but load the entire thread.  
Old June 8th, 2015 (12:54 AM). Edited July 13th, 2015 by azurile13.
azurile13 azurile13 is offline
 
Join Date: Mar 2015
Posts: 417
Quote:
Originally Posted by Lance32497 View Post
Hello guys, I'm trying to build a routine that lets the Var 8000 edit thePokémon data substructures(Bulbapedia term)
.... I had read the entire site but I can't find the RAM Address of that Pokemon Data substructure
Are you just asking how to edit things in it like IVs? Because if that's the case, there's no reason to "build a routine," as a vanilla rom already has it built in. You can just move/load to a few registers then call it. I'm on a phone now so I can't give it to you right now, but I could give it to you the next time I'm on my computer/ you could probably find it with a quick google.

Also, what do you mean by "that" RAM address? There are six party slots and 30 pokemon in each box.
  #330   Link to this post, but load the entire thread.  
Old June 8th, 2015 (3:12 AM).
GoGoJJTech's Avatar
GoGoJJTech GoGoJJTech is offline
(☞゚ヮ゚)☞ http://GoGoJJTech.com ☜(゚ヮ゚☜)
 
Join Date: Nov 2012
Location: Earth
Age: 24
Gender: Female
Nature: Jolly
Posts: 2,475
Quote:
Originally Posted by Lance32497 View Post
Hello guys, I'm trying to build a routine that lets the Var 8000 edit thePokémon data substructures(Bulbapedia term)
.... I had read the entire site but I can't find the RAM Address of that Pokemon Data substructure
Pokémon data tables are not copied to RAM, they're read from the ROM. You can't change them in real time because you can't edit them from the game. (Obviously)

You may want to have a special case of reading a different piece of data or something. But I'm here to tell you that what you're doing is impossible by normal means.
__________________
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
  #331   Link to this post, but load the entire thread.  
Old June 8th, 2015 (7:48 AM). Edited June 8th, 2015 by Lance32497.
Lance32497's Avatar
Lance32497 Lance32497 is offline
LanceKoijer of Pokemon_Addicts
 
Join Date: Aug 2014
Location: Criscanto town-Ginoa Region xD
Gender: Male
Nature: Adamant
Posts: 792
The reason why I'm looking for that is for the pokemon current experience, anyway please forgive me if this routine I created is too dumb, I'm trying to create a routine that var 8004 is the slot number, 8005 is the Stat 0 is Current HP, 1 is Total HP, 2 is Attack and so on, then in 8006 is XXYY where XX can be only be 00(Add YY) or 01(Subtract YY) and YY is the value to add or subtract
But yeah, when I call it in a script, the game freezes
Spoiler:

.text
.align 2
.thumb
.thumb_func

main:
push {r0-r4, lr}
ldr r0, var @loads the var 8004 in r0
ldrb r0, [r0] @loads the byte of var 8004
cmp r0, #0x05 @compares var 8004 into 5
bgt end @if greater than 5 jump to Label end
ldr r1, Stat @loads the Pokemon data into r1
mov r2, #0x64 @moves 64 in r2
mul r2, r0 @multiplies value of Var 8004 into by 64 so that it jumps to the data of the selected pokemon slot
add r1, r2, r1 @adds the product of r2 and r0 in r1 then places it to r1
first_loop:
mov r2, #0x0 @cleans r2
ldr r3, var @loads var 8004 in r3
ldrb r3, [r3, #0x02] loads the byte in var 8005
cmp r3, #0x06 compares var 8005 in 6, r3 is the Stat choices, Current Hp, Total Hp, Atk and etc
bgt end @if greater than, jumps to end
add r1, r3, r1 @adds the stat choice in the r1 so that the address is fixed, then places the sum in r1
second_loop:
ldr r2, var @loads var 8004 in
ldrb r2, [r2, #0x05] @loads the second byte of var 8006 in r2
cmp r2, #0x0 @compares r2 to 0
beq add2 @if equal, jump to add2
cmp r2, #0x1 @compares r2 to 1
bgt end @if greater than, jump to end
ldr r1, var @loads var 8004
ldrb r1, [r1, #0x4] loads the byte of var 8006
sub r1, r3, r1 @subtracts the stat offset and var 8006 then places the difference in r1
strb r1, [r1] @stores the byte or r1 in r1
b end @jumps to end
add2:
ldr, var @loads var 8004
ldrb, [r1, #0x4] @loads the byte in var 8006
add r1, r3, r1 @adds the stat offset to var 8006 then places the sum in rq
b end @jumps to end

end:
pop {r1-r4, pc} @pops all registers I used, AAAARRRRRGH! It should be pop {r0-r4, pc}

.align 2
var .word 0x020370c0
Stat .word 0x02024284
__________________
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.
  #332   Link to this post, but load the entire thread.  
Old June 8th, 2015 (10:35 AM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by Lance32497 View Post
The reason why I'm looking for that is for the pokemon current experience, anyway please forgive me if this routine I created is too dumb, I'm trying to create a routine that var 8004 is the slot number, 8005 is the Stat 0 is Current HP, 1 is Total HP, 2 is Attack and so on, then in 8006 is XXYY where XX can be only be 00(Add YY) or 01(Subtract YY) and YY is the value to add or subtract
But yeah, when I call it in a script, the game freezes
Spoiler:

.text
.align 2
.thumb
.thumb_func

main:
push {r0-r4, lr}
ldr r0, var
ldrb r0, [r0]
cmp r0, #0x05
bgt end
ldr r1, Stat
mov r2, #0x64
mul r2, r0
add r1, r2, r1
first_loop:
mov r2, #0x0
ldr r3, var
ldrb r3, [r3, #0x02]
cmp r3, #0x06
bgt end
add r1, r3, r1
second_loop:
ldr r2, var
ldrb r2, [r2, #0x03]
cmp r2, #0x0
beq add2
cmp r2, #0x1
bgt end
ldr r1, var
ldrb r1, [r1, #0x4]
sub r1, r3, r1
strb r1, [r1]
b end
add2:
ldr, var
ldrb, [r1, #0x4]
add r1, r3, r1
b end

end:
pop {r1-r4, pc}

.align 2
var .word 0x020370c0
Stat .word 0x02024284
So much is wrong with this - the cause for the freeze being the least worrying. You label stuff as loops, yet they don't loop? Anyway, your main problem is you push more than you pop, thus causing stack corruption.

Please comment what you think you are doing so I can correct it - I can't guess what this is supposed to do without comments.
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
  #333   Link to this post, but load the entire thread.  
Old June 8th, 2015 (3:51 PM).
Lance32497's Avatar
Lance32497 Lance32497 is offline
LanceKoijer of Pokemon_Addicts
 
Join Date: Aug 2014
Location: Criscanto town-Ginoa Region xD
Gender: Male
Nature: Adamant
Posts: 792
Quote:
Originally Posted by Touched View Post
So much is wrong with this - the cause for the freeze being the least worrying. You label stuff as loops, yet they don't loop? Anyway, your main problem is you push more than you pop, thus causing stack corruption.

Please comment what you think you are doing so I can correct it - I can't guess what this is supposed to do without comments.
am already put the comment
__________________
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.
  #334   Link to this post, but load the entire thread.  
Old June 8th, 2015 (6:53 PM).
Q-orca Q-orca is offline
 
Join Date: Sep 2014
Gender: Male
Posts: 23
Quote:
Originally Posted by Lance32497 View Post
The reason why I'm looking for that is for the pokemon current experience, anyway please forgive me if this routine I created is too dumb, I'm trying to create a routine that var 8004 is the slot number, 8005 is the Stat 0 is Current HP, 1 is Total HP, 2 is Attack and so on, then in 8006 is XXYY where XX can be only be 00(Add YY) or 01(Subtract YY) and YY is the value to add or subtract
But yeah, when I call it in a script, the game freezes
Spoiler:

.text
.align 2
.thumb
.thumb_func

main:
push {r0-r4, lr} @(#1)
ldr r0, var @loads the var 8004 in r0
ldrb r0, [r0] @loads the byte of var 8004
cmp r0, #0x05 @compares var 8004 into 5
bgt end @if greater than 5 jump to Label end
ldr r1, Stat @loads the Pokemon data into r1
mov r2, #0x64 @moves 64 in r2
mul r2, r0 @multiplies value of Var 8004 into by 64 so that it jumps to the data of the selected pokemon slot
add r1, r2, r1 @adds the product of r2 and r0 in r1 then places it to r1
first_loop:
mov r2, #0x0 @cleans r2 (#2)
ldr r3, var @loads var 8004 in r3
ldrb r3, [r3, #0x02] loads the byte in var 8005
cmp r3, #0x06 compares var 8005 in 6, r3 is the Stat choices, Current Hp, Total Hp, Atk and etc
bgt end @if greater than, jumps to end
add r1, r3, r1 @adds the stat choice in the r1 so that the address is fixed, then places the sum in r1 (#3)
second_loop:
ldr r2, var @loads var 8004 in
ldrb r2, [r2, #0x05] @loads the second byte of var 8006 in r2
cmp r2, #0x0 @compares r2 to 0
beq add2 @if equal, jump to add2
cmp r2, #0x1 @compares r2 to 1
bgt end @if greater than, jump to end
ldr r1, var @loads var 8004 (#4)
ldrb r1, [r1, #0x4] loads the byte of var 8006 (#4)
sub r1, r3, r1 @subtracts the stat offset and var 8006 then places the difference in r1 (#5)
strb r1, [r1] @stores the byte or r1 in r1 (#6)
b end @jumps to end
add2:
ldr, var @loads var 8004 (#4)
ldrb, [r1, #0x4] @loads the byte in var 8006 (#4)
add r1, r3, r1 @adds the stat offset to var 8006 then places the sum in rq (#5, #6)
b end @jumps to end

end:
pop {r1-r4, pc} @pops all registers I used, AAAARRRRRGH! It should be pop {r0-r4, pc} (#1)

.align 2
var .word 0x020370c0
Stat .word 0x02024284


Spoiler:

#1: Since r4 won't be used, IMO {r0-r3,lr/pc} is safer. You should check available bytes in SP first
#2: This step is redundant.
#3: IIRC, it's 2 byte per stat, so you should multiply r3 by 2 first.
#4: r1 isn't usable due to #3. Use r0 instead.
#5: The value in r1 should be loaded first into r3 (ldrh). Then, use sub/add r3, r3, r0 instead, assuming you're using r0 and r3 as I've mentioned.
#6: At this rate, you should store the value of r3 into r1 (strh instead of strb). Also, put r3 between limit (0 - 999) before storing them.
  #335   Link to this post, but load the entire thread.  
Old June 8th, 2015 (7:20 PM).
Trainer 781
Guest
 
Posts: n/a
Does bls ignores the sign of operands or blt?
  #336   Link to this post, but load the entire thread.  
Old June 8th, 2015 (7:37 PM).
Q-orca Q-orca is offline
 
Join Date: Sep 2014
Gender: Male
Posts: 23
Quote:
Originally Posted by KDS View Post
Does bls ignores the sign of operands or blt?
From GBATEK, yes.
  #337   Link to this post, but load the entire thread.  
Old June 8th, 2015 (7:54 PM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by Q-orca View Post
#1: Since r4 won't be used, IMO {r0-r3,lr/pc} is safer. You should check available bytes in SP first
#2: This step is redundant.
#3: IIRC, it's 2 byte per stat, so you should multiply r3 by 2 first.
#4: r1 isn't usable due to #3. Use r0 instead.
#5: The value in r1 should be loaded first into r3 (ldrh). Then, use sub/add r3, r3, r0 instead, assuming you're using r0 and r3 as I've mentioned.
#6: At this rate, you should store the value of r3 into r1 (strh instead of strb). Also, put r3 between limit (0 - 999) before storing them.
#1: If he doesn't use R4 he doesn't need to push/pop any registers...
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
  #338   Link to this post, but load the entire thread.  
Old June 8th, 2015 (8:10 PM).
Q-orca Q-orca is offline
 
Join Date: Sep 2014
Gender: Male
Posts: 23
Quote:
Originally Posted by Touched View Post
#1: If he doesn't use R4 he doesn't need to push/pop any registers...
You're right, assuming that r0 - r3 aren't used every time he calls this routine.
  #339   Link to this post, but load the entire thread.  
Old June 8th, 2015 (9:13 PM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 23
Gender: Male
Posts: 409
Quote:
Originally Posted by Q-orca View Post
You're right, assuming that r0 - r3 aren't used every time he calls this routine.
It's not assuming, it's a standard. And may I ask how on earth you would check available space on the stack?
__________________
  #340   Link to this post, but load the entire thread.  
Old June 8th, 2015 (10:18 PM). Edited June 8th, 2015 by Q-orca.
Q-orca Q-orca is offline
 
Join Date: Sep 2014
Gender: Male
Posts: 23
Quote:
Originally Posted by daniilS View Post
It's not assuming, it's a standard. And may I ask how on earth you would check available space on the stack?
Since the only pokemon game I've ever hacked is R/S, I don't have any good example. In other GBA games, there are times where I need to push some registers (r0-r3) to insert a routine. I'm putting those just for insurance.

To check the availability of the stack, I'm checking all routines before and after this function. A function with SP modifying instruction can limit the space on the stack. If he calls the function inside a SP modifying function, there is a chance that pushing will overwrite important data.
  #341   Link to this post, but load the entire thread.  
Old June 9th, 2015 (4:56 AM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by Q-orca View Post
Since the only pokemon game I've ever hacked is R/S, I don't have any good example. In other GBA games, there are times where I need to push some registers (r0-r3) to insert a routine. I'm putting those just for insurance.

To check the availability of the stack, I'm checking all routines before and after this function. A function with SP modifying instruction can limit the space on the stack. If he calls the function inside a SP modifying function, there is a chance that pushing will overwrite important data.
Since the game was compiled, it follows a rather strict calling convention. This means that routines that are designed to be called as functions (i.e. they are called and then return) do not need push/pop r0-r3 because these are reserved for arguments and return values - a caller assumes the callee will alter these values. This is always the case for functions. However, you may need to push these registers if you are modify existing functions by hooking into a routine. However, since the question was about a routine that was called from a script, we know it is a function; the script handler and function code for callasm expect r0-r3 to be messed up, thus we need not push them. Another point I should make is that LR is not used therefore pushing it is not necessary.

I assume stack overflow (for the user stack at least) is incredibly unlikely unless you are implementing a recursive function that uses stack space or you are allocating an absurd amount of space on the stack; I highly doubt you could overflow the stack just by pushing once. Have you ever seen the stack overflow?
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
  #342   Link to this post, but load the entire thread.  
Old June 9th, 2015 (5:26 AM).
daniilS's Avatar
daniilS daniilS is offline
busy trying to do stuff not done yet
 
Join Date: Aug 2013
Age: 23
Gender: Male
Posts: 409
I think he was referring to functions reserving space on the stack. But even then, those adjust the stack pointer, so there's nothing to worry about.
__________________
  #343   Link to this post, but load the entire thread.  
Old June 11th, 2015 (5:28 PM).
MadHacker151 MadHacker151 is offline
 
Join Date: Jan 2015
Posts: 29
Hi, so I am still a bit new to asm (very new actually..) and I am trying to copy an 8 byte long piece of code from FireRed's RAM, and place it somewhere else. Is there any way I can do that? For example, it takes whatever is at (said offset) and places it somewhere else. It doesn't have to be cut and pasted either (it can) but it could also just be copied and pasted. Thank you
  #344   Link to this post, but load the entire thread.  
Old June 11th, 2015 (5:44 PM).
Lance32497's Avatar
Lance32497 Lance32497 is offline
LanceKoijer of Pokemon_Addicts
 
Join Date: Aug 2014
Location: Criscanto town-Ginoa Region xD
Gender: Male
Nature: Adamant
Posts: 792
Very soon I can fix the errors,
Loading the party slot is fine, it works perfectly
while Loading the Correct Stat isn't yet working, and
it only stores the value from 8006 in the stat, it doesn't add the current stat and the value in 8006

Spoiler:

.align 2
.thumb
.thumb_func

main:
push {r0-r3, lr}
ldr r0, Var_8004
ldrb r0, [r0]
ldr r1, Base_stat
mov r2, #0x64
mul r2, r0
add r1, r1, r2
ldr r0, Var_8004
ldrb r0, [r0, #0x02]
mov r2, #0x56
mov r3, #0x02
mul r0, r3
add r2, r0, r2
add r1, r1, r2
ldr r0, Var_8004
ldrb r0, [r0, #0x4]
lsr r0, #0x8
cmp r0, #0x1
bgt sub1
ldr r0, Var_8004
ldrb r0, [r0, #0x4]
add r1, r0, r1
strh r0, [r1]
cmp r1, #0xFF
bgt add_end
b end
sub1:
ldr r0, Var_8004
ldr r0, [r0, #0x4]
sub r1, r0, r1
strh r0, [r1]
cmp r1, #0x00
bgt sub_end
b end
add_end:
mov r1, #0xFF
b end
sub_end:
mov r1, #0x0
b end
end:
pop {r0-r3, pc}

.align 2
Var_8004: .word 0x020370c0
Base_stat: .word 0x02024284

__________________
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.
  #345   Link to this post, but load the entire thread.  
Old June 11th, 2015 (9:29 PM).
robinjea's Avatar
robinjea robinjea is offline
 
Join Date: Sep 2012
Age: 25
Gender: Male
Nature: Quirky
Posts: 534
Hey guys! I'm actually writing my very first (free-handed or should I say free-minded) routine and I'm stuck.
Is there something like a compare command in ASM?

Here's what I'm trying to do: Compare the values of 2 vars (0x8000 and 0x800D) and make it return to 0x800D 0x0 if 0x8000 is lower, 0x1 if it is equal and 0x2 if 0x8000 is greater than 0x800D. I just need instructions, not the code itself.

Oh and on a side note, when a var's value is 0 and when something is subtracted to it, it becomes 65535 minus the value you subtracted. Is there a way to counter this using ASM?
  #346   Link to this post, but load the entire thread.  
Old June 12th, 2015 (4:14 AM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by MadHacker151 View Post
Hi, so I am still a bit new to asm (very new actually..) and I am trying to copy an 8 byte long piece of code from FireRed's RAM, and place it somewhere else. Is there any way I can do that? For example, it takes whatever is at (said offset) and places it somewhere else. It doesn't have to be cut and pasted either (it can) but it could also just be copied and pasted. Thank you
There are a variety of ways you can do this, and most depend on the alignment of the destination and source addresses. If both addresses are word aligned, one can simply:

Code:
ldr r0, source
ldmia r0!, {r1-r2} @ loads two words (8 bytes) into r1 and r2 starting from r0
ldr r0, dest
stmia r0!, {r1-r2} @ opposite of ldmia - stores to r0

@ This is the same as swi 0xC and the word variant of swi 0xB
@ Use those for bigger copies
However if the addresses aren't word aligned, or you can't guarantee that they will be, you must resort to memcpy. There is already an implementation of this function - see the FireRed IDB for addresses and parameters. Its basically a loop with ldrb and strb.

Quote:
Originally Posted by Lance32497 View Post
Very soon I can fix the errors,
Loading the party slot is fine, it works perfectly
while Loading the Correct Stat isn't yet working, and
it only stores the value from 8006 in the stat, it doesn't add the current stat and the value in 8006

Spoiler:

.align 2
.thumb
.thumb_func

main:
push {r0-r3, lr}
ldr r0, Var_8004
ldrb r0, [r0]
ldr r1, Base_stat
mov r2, #0x64
mul r2, r0
add r1, r1, r2
ldr r0, Var_8004
ldrb r0, [r0, #0x02]
mov r2, #0x56

@ Avoid MUL if possible. Use LSL for multiplying by a power of two
mov r3, #0x02
mul r0, r3
add r2, r0, r2
add r1, r1, r2
ldr r0, Var_8004
ldrb r0, [r0, #0x4]
lsr r0, #0x8
cmp r0, #0x1
bgt sub1
ldr r0, Var_8004
ldrb r0, [r0, #0x4]
add r1, r0, r1
strh r0, [r1]
cmp r1, #0xFF
bgt add_end
b end
sub1:
ldr r0, Var_8004
ldr r0, [r0, #0x4]
sub r1, r0, r1
strh r0, [r1]
cmp r1, #0x00
bgt sub_end
b end
add_end:
mov r1, #0xFF
@ You don't need to b end before the end label - it "falls through" automatically
b end
sub_end:
mov r1, #0x0
b end
end:
@ You don't need to push/pop any registers. r0-r3 don't
@ needed to be push for functions and you're not calling anything.
@ A simple bx lr to return will do
pop {r0-r3, pc}

.align 2
Var_8004: .word 0x020370c0
Base_stat: .word 0x02024284

To add to the stat, load the current value of the stat, add to it, then store it. Keep in mind that this stat increase will be lost when the stats are recalculated, which is quite often.

I have commented where you can improve. You should also comment your routines (and don't just explain the opcodes, explain your intention) and break them up into logical sections so its easier on the eye to read.

Quote:
Originally Posted by BlackWhiteRobin View Post
Hey guys! I'm actually writing my very first (free-handed or should I say free-minded) routine and I'm stuck.
Is there something like a compare command in ASM?

Here's what I'm trying to do: Compare the values of 2 vars (0x8000 and 0x800D) and make it return to 0x800D 0x0 if 0x8000 is lower, 0x1 if it is equal and 0x2 if 0x8000 is greater than 0x800D. I just need instructions, not the code itself.

Oh and on a side note, when a var's value is 0 and when something is subtracted to it, it becomes 65535 minus the value you subtracted. Is there a way to counter this using ASM?
You will need to use a series of CMPs and conditional branches to set a register to the desired value. Then store the value in the target variable.

As for your second question on subtracting a value from 0: variables are treated as unsigned values by the scripting engine, so you couldn't use saved signed values reliably in a script. However, if you were to use the value only in ASM, you could use the load sign-extended halfword opcode (LDSH) to use that value as a signed half-word. This could represent -0x8000 to 0x7FFF. You would have to be careful to only load values you KNEW were signed with this, otherwise it could corrupt large unsigned values. It depends on what you want to use it for.
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
  #347   Link to this post, but load the entire thread.  
Old June 12th, 2015 (5:45 AM).
MadHacker151 MadHacker151 is offline
 
Join Date: Jan 2015
Posts: 29
Quote:
Originally Posted by Touched View Post
There are a variety of ways you can do this, and most depend on the alignment of the destination and source addresses. If both addresses are word aligned, one can simply:

Code:
ldr r0, source
ldmia r0!, {r1-r2} @ loads two words (8 bytes) into r1 and r2 starting from r0
ldr r0, dest
stmia r0!, {r1-r2} @ opposite of ldmia - stores to r0

@ This is the same as swi 0xC and the word variant of swi 0xB
@ Use those for bigger copies
However if the addresses aren't word aligned, or you can't guarantee that they will be, you must resort to memcpy. There is already an implementation of this function - see the FireRed IDB for addresses and parameters. Its basically a loop with ldrb and strb.
Thanks a ton! Hmm.. Well the address I'm trying to copy is a pointer to the code (the code is in different locations depending on the length the player chooses in game.. Its the player's name) so I can't exactly put the exact address of the code. I can put the offset of the pointer to it though right? (300500C)? Also, does the destination have to be in the ram or can it be in the game's offsets? Either should be fine. Thanks again.
  #348   Link to this post, but load the entire thread.  
Old June 12th, 2015 (1:45 PM).
robinjea's Avatar
robinjea robinjea is offline
 
Join Date: Sep 2012
Age: 25
Gender: Male
Nature: Quirky
Posts: 534
Quote:
Originally Posted by Touched View Post
You will need to use a series of CMPs and conditional branches to set a register to the desired value. Then store the value in the target variable.

As for your second question on subtracting a value from 0: variables are treated as unsigned values by the scripting engine, so you couldn't use saved signed values reliably in a script. However, if you were to use the value only in ASM, you could use the load sign-extended halfword opcode (LDSH) to use that value as a signed half-word. This could represent -0x8000 to 0x7FFF. You would have to be careful to only load values you KNEW were signed with this, otherwise it could corrupt large unsigned values. It depends on what you want to use it for.
Not to sound super noobish but how would I use THUMB.16 in a code? Like a sample or something?

I'd guess. THUMB.16 C I got that wrong didn't I?
  #349   Link to this post, but load the entire thread.  
Old June 13th, 2015 (5:28 AM).
Touched's Avatar
Touched Touched is offline
Resident ASMAGICIAN
 
Join Date: Jul 2014
Gender: Male
Posts: 625
Quote:
Originally Posted by MadHacker151 View Post
Thanks a ton! Hmm.. Well the address I'm trying to copy is a pointer to the code (the code is in different locations depending on the length the player chooses in game.. Its the player's name) so I can't exactly put the exact address of the code. I can put the offset of the pointer to it though right? (300500C)? Also, does the destination have to be in the ram or can it be in the game's offsets? Either should be fine. Thanks again.
You can't use a pointer to the pointer. You have to dereference it before copying, otherwise you'll copy the wrong thing. E.g.

Code:
ldr r0, =0x300500C
@ r0 is pointing to another pointer so copying from here will result in 
@ the pointer being copied, not the data
ldr r0, [r0] @ dereference
@ Now you can copy from/to r0 as it is now pointing to data
Of course, since the data is being moved constantly (probably with DMA), it's almost certainly word or halfword aligned (aligned copies will be faster). Check the alignment of the pointers in a debugger if you are unsure.

The destination of course has to be in the RAM, as you can't write to the ROM. The source can be in the ROM.

Quote:
Originally Posted by BlackWhiteRobin View Post
Not to sound super noobish but how would I use THUMB.16 in a code? Like a sample or something?

I'd guess. THUMB.16 C I got that wrong didn't I?
Uhh, that's the section number. I was referring to the opcodes BEQ, BNE, BCS etc. Those are called conditional branches because they jump to a different location if a certain condition is true. If you look at a tree diagram of the code, it forks the path of execution at the branches, hence the name. They're a way of performing certain actions only if a condition is true. You can do:

Code:
cmp r0, r1
beq equal
blo unsigned_lower
bhi unsigned_higher
Multiple branches in a row are okay because branches do not alter the CPSR, thus preserving the state set by the CMP operation.
__________________

A Pokemon that is discriminated!
Support squirtle and make it everyone's favourite.
  #350   Link to this post, but load the entire thread.  
Old June 13th, 2015 (7:29 AM). Edited June 13th, 2015 by MadHacker151.
MadHacker151 MadHacker151 is offline
 
Join Date: Jan 2015
Posts: 29
Quote:
Originally Posted by Touched View Post
You can't use a pointer to the pointer. You have to dereference it before copying, otherwise you'll copy the wrong thing. E.g.

Code:
ldr r0, =0x300500C
@ r0 is pointing to another pointer so copying from here will result in 
@ the pointer being copied, not the data
ldr r0, [r0] @ dereference
@ Now you can copy from/to r0 as it is now pointing to data
Of course, since the data is being moved constantly (probably with DMA), it's almost certainly word or halfword aligned (aligned copies will be faster).[URL="http://www.pokecommunity.com/#82366744"] Check the alignment of the pointers in a debugger if you are unsure.

The destination of course has to be in the RAM, as you can't write to the ROM. The source can be in the ROM.
That was a pretty foolish question, the ram or rom question.. Wasn't thinking straight :/ But anyway I tried dereferencing 300500C (at least I think) and it still will not copy it to the offset stated. Well, this is what I have:

Spoiler:
.text
.align 2
.thumb
.thumb_func

main:
push {r0-r2, lr}
ldr r0, .Source
ldr r0, [r0]
ldmia r0!, {r1-r2}
ldr r0, .Dest
stmia r0!, {r1-r2}
pop {r0-r2, pc}


.align 2
.Source:
.word 0x300500C

.Dest:
.word 0x84EE00


As you can see I did what you said by loading r0 again with ldr r0, [r0]. I guess it should copy it to 0x84EE00 (just a test offset I used), do you spot anything thats wrong or anything I'm missing? Sorry for so many questions.. I hope I'm not sounding rude :/ )
Closed Thread

Quick Reply

Join the conversation!

Create an account to post a reply in this thread, participate in other discussions, and more!

Create a PokéCommunity Account
Ad Content

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -8. The time now is 9:23 AM.