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
  #26   Link to this post, but load the entire thread.  
Old December 19th, 2014 (12:28 AM).
Red John's Avatar
Red John Red John is offline
Progressing Assembly hacker
 
Join Date: May 2014
Location: Where ever there is peace and darkness
Gender: Male
Nature: Lonely
Posts: 137
How do i make my routine read from a table? I think it would be different when hard coded or calling via script.
__________________
  #27   Link to this post, but load the entire thread.  
Old December 19th, 2014 (10:10 AM). Edited December 19th, 2014 by Blah.
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Knight of Duty View Post
How do i make my routine read from a table? I think it would be different when hard coded or calling via script.
You need to know the format of the table before you do anything. Most of the time tables in ROM are very easy, while tables in RAM require some sort of field for Table length. This is because

In ROM, it's rather simple to read pointer and data it look like this:
Code:
main:
	mov r2, #0x0
loop:
	ldr r0, .TableStart
	lsl r1, r2, #0x2 @data length (I'm assuming it's a pointer, so multiply by 4)
	add r0, r0, r1
	ldr r0, [r0] @new pointer in table
	lsr r1, r0, #0x18
	cmp r1, #0xFF @end of table, you may want to use 00 00 00 00 as the ending bytes, however.
	beq end
	@right now r0 contains a valid pointer in the table
	@you can bl to any other sub routines that utilize it here
	
next:
	add r2, r2, #0x1 @increment table counter
	b loop
In RAM, depending on the contents of the table you may need a table counter. For example, in my Roaming Pokemon data structure, it was not always 100% chance that the last X bytes would be "00" and on top of that I want to be able to see if an Xth one is there (I don't want to be loading garbage data). So a table counter is very nice. However, if you're just writing something like a short table of strings, you can determine the end of the table because 0xFF is the string terminating byte.

Code:
main:
	ldr r3, .TableLength
	mov r2, #0x0
loop:
	cmp r3, r2 @check if we're finished the table
	beq end
	ldr r0, .TableStart
	lsl r1, r2, #0x2 @data length (I'm assuming it's a pointer, so multiply by 4)
	add r0, r0, r1
	@right now, r0 contains a pointer to the start of the current data
	@you can bl to any other sub routines that utilize it here
	
next:
	add r2, r2, #0x1 @increment table counter
	b loop
You'll notice that I didn't need to check if it was the end of the table because I already know the length of the table. 1 extra byte in RAM space is saving up operation time. Worth? Yes.


Finally, the last and probably the best way is if you already know which index you want.

Code:
main:
	ldr r0, .TableStart
	mov r1, #0x[data length]
	mov r2, #0x[date index]
	mul r1, r1, r2
	add r0, r0, r1 @start of the new data
Hope this helps. If you have questions, feel free to ask here :)
__________________
...
  #28   Link to this post, but load the entire thread.  
Old December 25th, 2014 (6:07 AM).
Mickey` Mickey` is offline
 
Join Date: May 2011
Posts: 88
Hi,

Is it possible to call a XSE script from an ASM script ?
  #29   Link to this post, but load the entire thread.  
Old December 25th, 2014 (6:32 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Mickey` View Post
Hi,

Is it possible to call a XSE script from an ASM script ?
Yes. You would make a routine which passes the script to the script executor. That will run your script. A few posts before, someone was attempting something similar, take a look.
__________________
...
  #30   Link to this post, but load the entire thread.  
Old December 25th, 2014 (7:38 AM).
Mickey` Mickey` is offline
 
Join Date: May 2011
Posts: 88
I think I'm wrong {XD}

I have to simple XSE scripts. I want to call the second script in the first.

XSE script #1 (at 0x900000) :
Spoiler:

Code:
'---------------
#org 0x900000
callasm 0x8B00001
msgbox 0x8A00000 MSG_FACE '"Script 1"
end


'---------
' Strings
'---------
#org 0xA00000
= Script 1


XSE script #2 (at 0x910000) :
Spoiler:

Code:
'---------------
#org 0x910000
msgbox 0x8A10000 MSG_FACE '"Script 2"
end


'---------
' Strings
'---------
#org 0xA10000
= Script 2


And my ASM code (inserted at 0xB00000) :
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	ldr r0, SCRIPT_ADDRESS
	ldr r1, SCRIPT_EXECUTER
	bl linkerTwo
	pop {r0-r1, pc}

linkerTwo:
	bx r1
	
	
.align 2

SCRIPT_ADDRESS:
	.word 0x8910000 + 1

SCRIPT_EXECUTER:
	.word 0x8069B94 + 1


Note that the offset 69AE4 in an English Fire Red ROM corresponds with the offset 69B94 in a French Fire Red ROM (I use French ROMs).

The result of the first XSE script should be two messages, "Script 1" then "Script 2", right ? Instead of it, when I talk to a person with the first XSE script, I can hear the Bulbasaur's cry, and there isn't any message.

What's the matter ?
  #31   Link to this post, but load the entire thread.  
Old December 25th, 2014 (9:44 AM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Mickey` View Post
I think I'm wrong {XD}

I have to simple XSE scripts. I want to call the second script in the first.

XSE script #1 (at 0x900000) :
Spoiler:

Code:
'---------------
#org 0x900000
callasm 0x8B00001
msgbox 0x8A00000 MSG_FACE '"Script 1"
end


'---------
' Strings
'---------
#org 0xA00000
= Script 1


XSE script #2 (at 0x910000) :
Spoiler:

Code:
'---------------
#org 0x910000
msgbox 0x8A10000 MSG_FACE '"Script 2"
end


'---------
' Strings
'---------
#org 0xA10000
= Script 2


And my ASM code (inserted at 0xB00000) :
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	ldr r0, SCRIPT_ADDRESS
	ldr r1, SCRIPT_EXECUTER
	bl linkerTwo
	pop {r0-r1, pc}

linkerTwo:
	bx r1
	
	
.align 2

SCRIPT_ADDRESS:
	.word 0x8910000 + 1

SCRIPT_EXECUTER:
	.word 0x8069B94 + 1


Note that the offset 69AE4 in an English Fire Red ROM corresponds with the offset 69B94 in a French Fire Red ROM (I use French ROMs).

The result of the first XSE script should be two messages, "Script 1" then "Script 2", right ? Instead of it, when I talk to a person with the first XSE script, I can hear the Bulbasaur's cry, and there isn't any message.

What's the matter ?
Oh I see what you mean now. Well, I'm not sure how the limitations work for calling the script from ASM within a script. I'm pretty sure you're going to eventually overwrite parts of the stack. I would rather just use the scripting command "call" and have a return at the end of the second script. On another note, a quick peek at your routine tells me it doesn't look wrong :P
__________________
...
  #32   Link to this post, but load the entire thread.  
Old December 25th, 2014 (3:07 PM).
Mickey` Mickey` is offline
 
Join Date: May 2011
Posts: 88
Quote:
Originally Posted by FBI agent View Post
Oh I see what you mean now. Well, I'm not sure how the limitations work for calling the script from ASM within a script. I'm pretty sure you're going to eventually overwrite parts of the stack. I would rather just use the scripting command "call" and have a return at the end of the second script. On another note, a quick peek at your routine tells me it doesn't look wrong :P
Yes, of course, the command "call" is really easier to use, it was just to try the ASM code.

So, if I understand, I can call a XSE script only when I'm in an ASM script not called from another XSE script ? x)
  #33   Link to this post, but load the entire thread.  
Old December 25th, 2014 (3:11 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Mickey` View Post
Yes, of course, the command "call" is really easier to use, it was just to try the ASM code.

So, if I understand, I can call a XSE script only when I'm in an ASM script not called from another XSE script ? x)
Yeah, I don't think you can load and run two instances of the script execution routine at once.
__________________
...
  #34   Link to this post, but load the entire thread.  
Old December 25th, 2014 (4:08 PM).
Mickey` Mickey` is offline
 
Join Date: May 2011
Posts: 88
Okay ! Another question related to the previous one : is it possible to run an XSE script from an item, changing the "Field Usage Code Pointer" in Item Editor ?
  #35   Link to this post, but load the entire thread.  
Old December 25th, 2014 (10:31 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by Mickey` View Post
Okay ! Another question related to the previous one : is it possible to run an XSE script from an item, changing the "Field Usage Code Pointer" in Item Editor ?
Yes, doing this has been documented in two different ways I know of, by davidjcobb (who uses JPAN's engine) and Darthatron who uses the script executor.
__________________
...
  #36   Link to this post, but load the entire thread.  
Old December 26th, 2014 (3:21 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
Quote:
Originally Posted by Mickey` View Post
I think I'm wrong {XD}

I have to simple XSE scripts. I want to call the second script in the first.

XSE script #1 (at 0x900000) :
Spoiler:

Code:
'---------------
#org 0x900000
callasm 0x8B00001
msgbox 0x8A00000 MSG_FACE '"Script 1"
end


'---------
' Strings
'---------
#org 0xA00000
= Script 1


XSE script #2 (at 0x910000) :
Spoiler:

Code:
'---------------
#org 0x910000
msgbox 0x8A10000 MSG_FACE '"Script 2"
end


'---------
' Strings
'---------
#org 0xA10000
= Script 2


And my ASM code (inserted at 0xB00000) :
Spoiler:

Code:
.text
.align 2
.thumb
.thumb_func

main:
	push {r0-r1, lr}
	ldr r0, SCRIPT_ADDRESS
	ldr r1, SCRIPT_EXECUTER
	bl linkerTwo
	pop {r0-r1, pc}

linkerTwo:
	bx r1
	
	
.align 2

SCRIPT_ADDRESS:
	.word 0x8910000 + 1

SCRIPT_EXECUTER:
	.word 0x8069B94 + 1


Note that the offset 69AE4 in an English Fire Red ROM corresponds with the offset 69B94 in a French Fire Red ROM (I use French ROMs).

The result of the first XSE script should be two messages, "Script 1" then "Script 2", right ? Instead of it, when I talk to a person with the first XSE script, I can hear the Bulbasaur's cry, and there isn't any message.

What's the matter ?
In your routine, you don't need the +1 at the script address. And I expect "Script 2" to be shown before "Script 1", and maybe just Script 2.
__________________
  #37   Link to this post, but load the entire thread.  
Old December 26th, 2014 (3:51 AM). Edited December 26th, 2014 by Mickey`.
Mickey` Mickey` is offline
 
Join Date: May 2011
Posts: 88
Another problem :(

I used the Darthatron's code, and it works, but only when I use my item pressing Select. If I click on "Use" in the bag, nothing happens, except the bag closes (but no crash).

Here's the ASM code with French Offsets :
Spoiler:
Code:
.text
.align 2
.thumb
.thumb_func
.global Hax
	
setup:
	push {r4, lr}
	mov r4, r0
	mov r0, pc
	add r0, #0x13
	ldr r1, .unk_02039998
	str r0, [r1]
	mov r0, r4
	ldr r1, .sub_080A11E8
	bl bx_r1
	pop {r4}
	pop {r0}
	bx r0

main:
	push {r4, lr}
	mov r4, r0
	ldr r0, .ScriptToCall
	ldr r1, .CallScript
	bl bx_r1
	mov r0, r4
	ldr r1, .del_c3_from_linked_list
	bl bx_r1
	pop {r4}
	pop {r0}
	bx r0

.align 2
bx_r1:
	bx r1

.align 2
.CallScript:
	.word 0x08069B94 + 1
.unk_02039998:
	.word 0x02039998
.sub_080A11E8:
	.word 0x080A11E8 + 1
.del_c3_from_linked_list:
	.word 0x0807752C + 1
.ScriptToCall:
	.word 0x08900000


My XSE script is compiled at 0x900000. In Item Editor, I put C00001 at "Field Usage Code Pointer", because my ASM code is compiled to 0xC00000.


EDIT : I didn't see your post !

Quote:
Originally Posted by daniilS View Post
In your routine, you don't need the +1 at the script address. And I expect "Script 2" to be shown before "Script 1", and maybe just Script 2.
You're right, it works ! And effectively, just "Script 2" is shown.

But I can't use XSE scripts with items if I don't register them...
  #38   Link to this post, but load the entire thread.  
Old December 26th, 2014 (2:48 PM).
JoshTheTrainer's Avatar
JoshTheTrainer JoshTheTrainer is offline
Glaceon Lover ~
 
Join Date: May 2009
Location: The Netherlands
Gender: Male
Nature: Gentle
Posts: 101
Quote:
Originally Posted by FBI agent View Post
Oh, I've done some research on this before :D

The Map's name is based on the map value (I think that's what it's called), it's a byte in the map header.
You will need to change this to an unused byte value and then do some editing\expansion on the routine at 080C4D78. This routine takes the following parameters:
r0: Location to store string
r1: Map value byte (I was just talking about)
r2: ??? I just use 0x0, though for your purposes it doesn't matter.

Basically it's the routine that will read Map names. There's some calculations and stuff that go on in there which you may want to edit slightly for it to return a map name of your liking. The easiest way is to hook from the start, make an exception case for your specific map value.

Code:
Main:
	push {r0-r3}
	cmp r1, #0x[your custom map value]
	bne default

forceName:
	ldr r1, =(0x8[pointer to your map's name in hex])
	ldr r2, =(0x8008D84 +1) @str_cpy
	bl linker
	b end

linker:
	bx r2

default:
	pop {r0-r3}
	@restore overwritten instructions
	@bx to appropriate location to continue safely
	@note these comments are for you to fill in with the appropriate assembly instructions

end:
	pop {r0-r3}
	ldr r4, =(0x80C4DF2 +1)
	bx r4

Hopefully that helps (it should, as I practically spoon fed you the solution :P). If you have ASM questions ask in the Assembly Help thread :D
I was wondering if somebody can explain me more of this. For example, I know it's ASM but how do I insert it in my rom? Do I need to disassemble it and go to the right 'memory location' or what? Sorry if I sound a bit noobish but I'm not an expert.
__________________
  #39   Link to this post, but load the entire thread.  
Old December 26th, 2014 (2:50 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by JoshTheTrainer View Post
I was wondering if somebody can explain me more of this. For example, I know it's ASM but how do I insert it in my rom? Do I need to disassemble it and go to the right 'memory location' or what? Sorry if I sound a bit noobish but I'm not an expert.
You would insert it right after the push for the function, which would be at 080C4D7A. Though you may obviously note that this is not a word aligned offset so you'd pad it with 2 bytes of zeros to reach 080C4D7C. From there you insert to that offset in a hex editor, the hex you get after compiling:
Code:
ldr r6, =(0x8[Custom snip +1])
bx r6
Custom snip would be the pointer to map name assigning routine from last post +1. You may notice we've overwritten some instructions for our little jump. You have to edit
Code:
default:
	pop {r0-r3}
	@restore overwritten instructions
	@bx to appropriate location to continue safely
	@note these comments are for you to fill in with the appropriate assembly instructions
to include those instructions, and use a safe register to return to some non-junk code which would run subsequently after and at the same time not mess up existing register values.
__________________
...
  #40   Link to this post, but load the entire thread.  
Old December 26th, 2014 (3:02 PM).
JoshTheTrainer's Avatar
JoshTheTrainer JoshTheTrainer is offline
Glaceon Lover ~
 
Join Date: May 2009
Location: The Netherlands
Gender: Male
Nature: Gentle
Posts: 101
Quote:
Originally Posted by FBI agent View Post
You would insert it right after the push for the function, which would be at 080C4D7A. Though you may obviously note that this is not a word aligned offset so you'd pad it with 2 bytes of zeros to reach 080C4D7C. From there you insert to that offset in a hex editor, the hex you get after compiling:
Code:
ldr r6, =(0x8[Custom snip +1])
bx r6
Custom snip would be the pointer to map name assigning routine from last post +1. You may notice we've overwritten some instructions for our little jump. You have to edit
Code:
default:
	pop {r0-r3}
	@restore overwritten instructions
	@bx to appropriate location to continue safely
	@note these comments are for you to fill in with the appropriate assembly instructions
to include those instructions, and use a safe register to return to some non-junk code which would run subsequently after and at the same time not mess up existing register values.
And that's in the assembly of my rom, right? So I just need a disassembler and assembler or is it just basic script editing?
__________________
  #41   Link to this post, but load the entire thread.  
Old December 26th, 2014 (3:09 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by JoshTheTrainer View Post
And that's in the assembly of my rom, right? So I just need a disassembler and assembler or is it just basic script editing?
This is done in hex, you can use the disassembler builtin in the VBA Emulator for this level of work.
__________________
...
  #42   Link to this post, but load the entire thread.  
Old December 26th, 2014 (3:16 PM).
JoshTheTrainer's Avatar
JoshTheTrainer JoshTheTrainer is offline
Glaceon Lover ~
 
Join Date: May 2009
Location: The Netherlands
Gender: Male
Nature: Gentle
Posts: 101
Quote:
Originally Posted by FBI agent View Post
This is done in hex, you can use the disassembler builtin in the VBA Emulator for this level of work.
Oh okay, I'll try it out. Thanks anyway :-)
__________________
  #43   Link to this post, but load the entire thread.  
Old December 26th, 2014 (4:27 PM).
Joexv's Avatar
Joexv Joexv is offline
ManMadeOfGouda
joexv.github.io
 
Join Date: Oct 2012
Location: Oregon
Age: 25
Gender: Male
Nature: Sassy
Posts: 1,035
Alright, Fbi Agent how would I go about adding the flag check to the routines like you suggested?
Is it just adding this to it?
Code:
push {r0-r4}
	mov r0, #0xBF @flag to check divided by 4
	lsl r0, r0, #0x2
__________________
New living flesh vessel who dis?
  #44   Link to this post, but load the entire thread.  
Old December 26th, 2014 (4:52 PM).
HidoranBlaze's Avatar
HidoranBlaze HidoranBlaze is offline
 
Join Date: Apr 2013
Age: 26
Gender: Male
Posts: 252
Quote:
Originally Posted by joexv View Post
Alright, Fbi Agent how would I go about adding the flag check to the routines like you suggested?
Is it just adding this to it?
Code:
push {r0-r4}
	mov r0, #0xBF @flag to check divided by 4
	lsl r0, r0, #0x2
If you want to check a flag in one of your routines, you'll have to bl call the flag decrypt function, which takes the flag you want to check in r0, and returns the status of that flag to r0. I forget where that function was in FR, but basically do something like this:
(load flag # in r0)
...
bl flagcheck

flagcheck:
ldr r1, function
bx r1

You can use any free register of course, I just used r1 as an example. Hope this helps.
  #45   Link to this post, but load the entire thread.  
Old December 26th, 2014 (5:17 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by HidoranBlaze View Post
If you want to check a flag in one of your routines, you'll have to bl call the flag decrypt function, which takes the flag you want to check in r0, and returns the status of that flag to r0. I forget where that function was in FR, but basically do something like this:
(load flag # in r0)
...
bl flagcheck

flagcheck:
ldr r1, function
bx r1

You can use any free register of course, I just used r1 as an example. Hope this helps.
Yeah, but I make a point to have to ldr in the main function body. That way you can use the linker for more than just a single case. I also believe it's slightly more readable (maybe :P).

But yeah, what HidoranBlaze did is what you'd do. Make sure to push the low registers you want to save before calling the function, it overwrites r0-r3 :D
__________________
...
  #46   Link to this post, but load the entire thread.  
Old December 26th, 2014 (7:16 PM).
Joexv's Avatar
Joexv Joexv is offline
ManMadeOfGouda
joexv.github.io
 
Join Date: Oct 2012
Location: Oregon
Age: 25
Gender: Male
Nature: Sassy
Posts: 1,035
Quote:
Originally Posted by FBI agent View Post
Yeah, but I make a point to have to ldr in the main function body. That way you can use the linker for more than just a single case. I also believe it's slightly more readable (maybe :P).

But yeah, what HidoranBlaze did is what you'd do. Make sure to push the low registers you want to save before calling the function, it overwrites r0-r3 :D
Ok, but how would I load the flag number into bl?
I suck at asm so sry for any stupid questions.
__________________
New living flesh vessel who dis?
  #47   Link to this post, but load the entire thread.  
Old December 26th, 2014 (7:40 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by joexv View Post
Ok, but how would I load the flag number into bl?
I suck at asm so sry for any stupid questions.
The flag checking function is a subroutine. If you're familiar with other programming languages they call things like these "functions" or sometimes "methods'.

Anyways, the flag checker function has a parameter which is the flag number. By definition, this parameter would be in r0. So you would just load into r0 your flag's number and then call the flag checker function.

The process of how we're "calling" the subroutine is a little harder to understand. It's a clever trick having to do with manipulation of the Stack. You see, bl is limited to within approximately 20 bytes (I don't recall the exact amount, but around that neighborhood) and obviously the function we're calling is somewhere near the start of the ROM (definitely not 20 bytes), so the only good way to get to it is to use bx. However, bx doesn't have a return, because it doesn't write anything to the lr. So we use this convention of bl to a bx, because bl overwrites the current lr value. So that way once the subroutine we call ends, it will go back to where the lr is pointing. However, it's important to note that bl overwrites lr without preserving it, so to make sure you're not messing anything up, push {lr} before doing any links, unless you know what you're doing :D

To answer your question, you're not loading the flag number into lr, you're going to be loading the flag number into r0, then doing the aforementioned method to link to the flag checker subroutine. That routine would, again by definition, return 0 or 1 in r0. So after your link, you would simply check r0.

Hopefully that made sense, I'm not very good at explaining.
__________________
...
  #48   Link to this post, but load the entire thread.  
Old December 26th, 2014 (8:05 PM).
Joexv's Avatar
Joexv Joexv is offline
ManMadeOfGouda
joexv.github.io
 
Join Date: Oct 2012
Location: Oregon
Age: 25
Gender: Male
Nature: Sassy
Posts: 1,035
Quote:
Originally Posted by FBI agent View Post
The flag checking function is a subroutine. If you're familiar with other programming languages they call things like these "functions" or sometimes "methods'.

Anyways, the flag checker function has a parameter which is the flag number. By definition, this parameter would be in r0. So you would just load into r0 your flag's number and then call the flag checker function.

The process of how we're "calling" the subroutine is a little harder to understand. It's a clever trick having to do with manipulation of the Stack. You see, bl is limited to within approximately 20 bytes (I don't recall the exact amount, but around that neighborhood) and obviously the function we're calling is somewhere near the start of the ROM (definitely not 20 bytes), so the only good way to get to it is to use bx. However, bx doesn't have a return, because it doesn't write anything to the lr. So we use this convention of bl to a bx, because bl overwrites the current lr value. So that way once the subroutine we call ends, it will go back to where the lr is pointing. However, it's important to note that bl overwrites lr without preserving it, so to make sure you're not messing anything up, push {lr} before doing any links, unless you know what you're doing :D

To answer your question, you're not loading the flag number into lr, you're going to be loading the flag number into r0, then doing the aforementioned method to link to the flag checker subroutine. That routine would, again by definition, return 0 or 1 in r0. So after your link, you would simply check r0.

Hopefully that made sense, I'm not very good at explaining.
OK that makes slightly more sense... but I'm still confused as to how im loading the flag number and value.
I understand that ldr reads so it would require that. But a way that i've learned helps me learn is to examine premade code. And looking at yours
Code:
main
	push {r0-r4}
	mov r0, #0xBF @flag to check divided by 4
	lsl r0, r0, #0x2
	ldr r1, =(0x806E6D0 +1)
	bl linker
	cmp r0, #0x0
	beq noCrash
	ldr r4, .table
Im having troubles understanding it. How does it get where the flag is stored and the value? And how does it check it?
__________________
New living flesh vessel who dis?
  #49   Link to this post, but load the entire thread.  
Old December 26th, 2014 (8:18 PM).
Blah's Avatar
Blah Blah is offline
Free supporter
 
Join Date: Jan 2013
Location: Unknown Island
Gender: Male
Posts: 1,924
Quote:
Originally Posted by joexv View Post
OK that makes slightly more sense... but I'm still confused as to how im loading the flag number and value.
I understand that ldr reads so it would require that. But a way that i've learned helps me learn is to examine premade code. And looking at yours
Code:
main
	push {r0-r4}
	mov r0, #0xBF @flag to check divided by 4
	lsl r0, r0, #0x2
	ldr r1, =(0x806E6D0 +1)
	bl linker
	cmp r0, #0x0
	beq noCrash
	ldr r4, .table
Im having troubles understanding it. How does it get where the flag is stored and the value? And how does it check it?
0x806E6D0 that's the function for reading the flag. It does everything internally including finding/checking and simply returns a 0 or 1 (unset or set) in r0.
__________________
...
  #50   Link to this post, but load the entire thread.  
Old December 26th, 2014 (8:22 PM).
Joexv's Avatar
Joexv Joexv is offline
ManMadeOfGouda
joexv.github.io
 
Join Date: Oct 2012
Location: Oregon
Age: 25
Gender: Male
Nature: Sassy
Posts: 1,035
Quote:
Originally Posted by FBI agent View Post
0x806E6D0 that's the function for reading the flag. It does everything internally including finding/checking and simply returns a 0 or 1 (unset or set) in r0.
Ohhh.. Ok.
So inorder to check a new flag it would be
Code:
	push {r0-r4}
	mov r0, #0x40
	lsl r0, r0, #0x2
	ldr r1, =(0x806E6D0 +1)
	cmp r0, #0x0
To check flag 0x160 right?
If so how then would I stop the script if its not set?
Would it be?
Code:
beq noscript @wheres noscript is another hunk a code
__________________
New living flesh vessel who dis?
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
Thread Tools

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