• Just a reminder that providing specifics on, sharing links to, or naming websites where ROMs can be accessed is against the rules. If your post has any of this information it will be removed.
  • Ever thought it'd be cool to have your art, writing, or challenge runs featured on PokéCommunity? Click here for info - we'd love to spotlight your work!
  • Our weekly protagonist poll is now up! Vote for your favorite Trading Card Game 2 protagonist in the poll by clicking here.
  • 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.
JPAN said in his guide:



After that he said a lot to explain how to solve the problem of misaligned code, such as adding "add r0, r0, #0x0" or other code without real meaning. I could not understand the above quoted words so I couldn't get what he said.
Could anyone help or give me an example? That will be very appreciated. :)

I think he is misinformed? Using ldr to load values/pointers consecutively proves no problem. Most of the time the pointers are stored as "definitions" at the end of the routine after compilation.

Code:
ldr r0, =(0xsomething)
ldr r1, =(0xSomethingElse)
works without a problem, for example. I don't think there is a distinction in functionality if you loaded from a label instead.
 
So here is my full code, it doesn't compile.
Spoiler:

I don't see where the problem is.

I also tried this:
Spoiler:
 
Last edited:
So here is my full code, it doesn't compile.
Spoiler:

I don't see where the problem is.

You're still doing the same thing.
Code:
    beq add r1, #0x1
Is a syntax error. Read how to use the "b" commands. They don't work like that :x
 
Ok thanks so i corrected the errors. It compiles but when the routine is called the game freezes.
Spoiler:
 
Ok thanks so i corrected the errors. It compiles but when the routine is called the game freezes.
Spoiler:

1) Make sure your routine is word aligned
2) Make sre you didn't forget to do +1 in the callasm
3) In your VBA emulator, run the game uptil this point. When I freezes, open VBA's debugger and tick the "thumb" box on the top as well as the "automatically update" box. With the disassembler on the side, keep running your game. If it's frozen at a certain address that means that one of your labels were invalid. It's a trick I normally use if my game freezes on me.

There's a good chance that this isn't the case. Try to debug your routine in a debugger VBA-SDL-H or something similar, step through it and see what's happening.

It's hard for anyone to tell what's wrong without really knowing what you've done. The source looks fine from my point of view.
 
Last edited:
I think that the problem is here :
Code:
ldr r2, .ATTUSER
	ldrb r2, [r2]
The division works well. But when it branches to the 8th step the game does nothing and freezes. The address of the user's index is not loaded.
 
I think that the problem is here :
Code:
ldr r2, .ATTUSER
	ldrb r2, [r2]
The division works well. But when it branches to the 8th step the game does nothing and freezes. The address of the user's index is not loaded.

No, this is fine I think. Uhh, my only complaint is that you shouldn't randomize the indentation like that. Try a different name excluding ".ATTUSER". Something like Attack_user without the period.
 
No, this is fine I think. Uhh, my only complaint is that you shouldn't randomize the indentation like that. Try a different name excluding ".ATTUSER". Something like Attack_user without the period.
Sorry for the indentation, it is like that due to copy/paste and I didn't preview my post.
So i modified my syntax. I replaced:
Code:
ldr r2, .ATTUSER
...
.ATTUSER:
	.word 0x0202420B
with
Code:
ldr r2, = (0x0202420B)
There is any changes.

When the game freezes, in the disassembler mode if we check registers we can see that r2 has 0x03. It never loads 0x0202420B (called "ATTUSER").

Edit:
I was right, I made a mistake at the 8th step
Code:
ldr r2, = (0x0202420B)
r2 never loaded the value, because i didn't write "eighth", but I wrote "eigth", "eight" and "eihgth", in only five lines...
I really have to learn my English. And I also have to sleep, sorry.

I also corrected a mistake. I replace "higher than" by "higher or same". Because in the case of "same" it didn't do anything.

So i post my final (I hope!) code:
Code:
.text
.align 2
.thumb
.thumb_func
.global main

main:
	push {r0-r3, lr}
	
	ldr r0, = (0x020241F0)
	
	ldrh r1, [r0]
	mov r2, #0x3
        mul r1, r2
        lsr r1, #2
        cmp r1, #0x0
        beq nineth
	b eighth

nineth:
	add r1, #0x1
	b eighth
	
eighth:
	ldr r2, = (0x0202420B)
	ldrb r2, [r2]
	
	cmp r2, #0x0
	beq fourth
	cmp r2, #0x1
	beq fifth
	cmp r2, #0x2
	beq sixth
	cmp r2, #0x3
	beq seventh
	b end

fourth:
	ldr r0, = (0x02024542)
	b third
	
fifth:
	ldr r0, = (0x0202479A)
	b third
	
sixth:
	ldr r0, = (0x020245A6)
	b third

seventh:
	ldr r0, = (0x020247FE)
	b third
	
third:
	mov r2, r0
	ldrh r3, [r0]
	
	add r2, #0x2
	ldrh r2, [r2]
	
	add r1, r3
	
	cmp r1, r2
	bhs first
	cmp r1, r2
	blo second
	b end
	
second:
	strh  r1, [r0]
	b end
	
first:
	strh  r2, [r0]
	b end
	
end:
	pop {r0-r3, pc}
	
.align 2
Thank you for your help!
 
Last edited:
I think he is misinformed? Using ldr to load values/pointers consecutively proves no problem. Most of the time the pointers are stored as "definitions" at the end of the routine after compilation.

Code:
ldr r0, =(0xsomething)
ldr r1, =(0xSomethingElse)
works without a problem, for example. I don't think there is a distinction in functionality if you loaded from a label instead.

Thank you for your reply. I will say what I know now:
JPAN said that ldr rX, Lable is actually ldr rX, [pc, #0ximm] so it has a limitation that the label shouldn't be too far away from the ldr instruction, which is what I think I get.
I think another things he said means that ldr can only fetch lables 4,8,16,...... bytes away from it.
I do not understand the things he said below:
That is because Ldr is a 32-bit Word fetching operation, and when added to the PC offset, the offset is shifted by two before adding to the address. That was made to make people's lives easier, allowing to fetch words that are not 127 but 508 bytes away.

I can't understand it even a bit...
 
Thank you for your reply. I will say what I know now:
JPAN said that ldr rX, Lable is actually ldr rX, [pc, #0ximm] so it has a limitation that the label shouldn't be too far away from the ldr instruction, which is what I think I get.
I think another things he said means that ldr can only fetch lables 4,8,16,...... bytes away from it.
I do not understand the things he said below:


I can't understand it even a bit...

Basically, from this whole thing, all you need to take away is that, "labels can only be accessed by OP codes which are about 254~ lines above the label" - according to JPAN. His use of this in the document, actually contradicts what he implies, because he does this even though he's writing a very small snipplet of code. As far as my knowledge goes, is unneeded. I'm also not a very big fan of his style of coding, I find it highly inefficient on top of being unneedingly complicated. You might want to wait to here daniilS opinion on this, as he is more technically intune with ASM instruction via his study at GBATEK. I for one can't be bothered to read all of that :P

Not to insult JPAN, he's been a very positive contribution to the ROM hacking community.

All you should know is that ldr loads into a register 4 bytes of data. If it's loading data from a pointer, that pointer must be word aligned (i.e divisible by 4) to be read properly.
 
Basically, from this whole thing, all you need to take away is that, "labels can only be accessed by OP codes which are about 254~ lines above the label" - according to JPAN. His use of this in the document, actually contradicts what he implies, because he does this even though he's writing a very small snipplet of code. As far as my knowledge goes, is unneeded. I'm also not a very big fan of his style of coding, I find it highly inefficient on top of being unneedingly complicated. You might want to wait to here daniilS opinion on this, as he is more technically intune with ASM instruction via his study at GBATEK. I for one can't be bothered to read all of that :P

Not to insult JPAN, he's been a very positive contribution to the ROM hacking community.

All you should know is that ldr loads into a register 4 bytes of data. If it's loading data from a pointer, that pointer must be word aligned (i.e divisible by 4) to be read properly.

That is to say there's no need to add any ".hword 0x0000" in any code?
Another question: Could you tell me more about the .align? At first I think it align the code to be 2-byte long, but why should we add another before defining the labels?

Thank you very much for your patient reply!
 
That is to say there's no need to add any ".hword 0x0000" in any code?
Another question: Could you tell me more about the .align? At first I think it align the code to be 2-byte long, but why should we add another before defining the labels?

Thank you very much for your patient reply!

I suggest always just leaving it in there, because during compile time the assembler will ignore it if it isn't needed. In the end it doesn't really impact your code in an unhealthy way, so I just leave it in for everything. You might here someone like daniilS come in and say stuff about not using it unneedingly , but it ultimately causes no harm while causing good in some cases. So just have it there all the time.

.align 2, iirc, just tells the assembler to start working on an address which is divisible by 2^n, in this case it's 2^2, i.e 4. It becomes important depending on context. You don't particularly need it in many cases, but in some cases you do. So like I said, just keep it there all the time.
 
I suggest always just leaving it in there, because during compile time the assembler will ignore it if it isn't needed. In the end it doesn't really impact your code in an unhealthy way, so I just leave it in for everything. You might here someone like daniilS come in and say stuff about not using it unneedingly , but it ultimately causes no harm while causing good in some cases. So just have it there all the time.

.align 2, iirc, just tells the assembler to start working on an address which is divisible by 2^n, in this case it's 2^2, i.e 4. It becomes important depending on context. You don't particularly need it in many cases, but in some cases you do. So like I said, just keep it there all the time.

OK, I will add ".hword 0x0000" in my code. :)
For the ".align num" issue:
2^2? For a word(always in the end of a routine) occupies 4 bytes, it's good. Why should we add ".align 2" instead of ".align 1" at the beginning of a routine as a thumb instruction occupies only 2 bytes? Also, some people write ".align" instead of ".align 2" before the lables in the end of their routines, could you tell me the reason?

Thank you.:)
 
OK, I will add ".hword 0x0000" in my code. :)
For the ".align num" issue:
2^2? For a word(always in the end of a routine) occupies 4 bytes, it's good. Why should we add ".align 2" instead of ".align 1" at the beginning of a routine as a thumb instruction occupies only 2 bytes? Also, some people write ".align" instead of ".align 2" before the lables in the end of their routines, could you tell me the reason?

Thank you.:)

.align without a number does nothing I believe (it's the same as aligning for 1 byte?). The .align2 before labels is because sometimes you have an ldr which requires word alignment. I'm not to familiar with the topic because adding .align 2 makes it unneeded to be explored.
 
.align without a number does nothing I believe (it's the same as aligning for 1 byte?). The .align2 before labels is because sometimes you have an ldr which requires word alignment. I'm not to familiar with the topic because adding .align 2 makes it unneeded to be explored.

So I can just simply add two .align 2, one at the beginning of the routine and another before the labels in the end?
 
So I can just simply add two .align 2, one at the beginning of the routine and another before the labels in the end?

Indeed you can. It covers all cases, as the other cases as subsets of this one. It's also ignored by the compiler if it's unneeded. The perfect thing to use without knowing anything about it lol.
 
Indeed you can. It covers all cases, as the other cases as subsets of this one. It's also ignored by the compiler if it's unneeded. The perfect thing to use without knowing anything about it lol.

OK,I will just use that method. Thank you very much though I still know nothing about it, at least I have a feasible way to do it XD
 
Summary:
The only thing you actually need at the beginning is .thumb, .align 2 can be used but there is no reason to do so, it's just if you like typing too much.
Put .align 2 before the words at the end and you will never need to worry about .hword 0x0, which could take up space or even misalign.
 
Summary:
The only thing you actually need at the beginning is .thumb, .align 2 can be used but there is no reason to do so, it's just if you like typing too much.
Put .align 2 before the words at the end and you will never need to worry about .hword 0x0, which could take up space or even misalign.

I use Hackmew's thumb assembler, so what should I do?
Most people do that:
.text
.align 2
.thumb
.thumb_func
....(functions)
.align 2
....(words)

Did you mean:
.thumb
....(functions)
.align 2
....(words)
 
Status
Not open for further replies.
Back
Top