Let's Make a Skill (ASM)

But wait…

Summary

I thought you were going to teach me to make skills. These are all stupid functions that affect everyone!

Okay, fine. The only difference between these functions and a skill is a few lines of code: we call the SkillTester function with the parameter of unit struct and Skill ID, which tells us true or false.

@ < my code > 
mov r0, r4 @ unit struct 
mov r1, #1 @ Skill ID (Canto is probably 1) 
bl SkillTester
cmp r0, #0 
beq End
@ code effect 

End: 
@ < my code> 

Now since we don’t want to hardcode our skill ID, we can instead load the name of the skill.

mov r0, r4 @ unit struct 
ldr r1, =CantoID 
mov r2, #0xFF 
and r1, r2 
bl SkillTester
cmp r0, #0 
beq End
@ code effect 

End:

That’s all there is to it! There are a number of ways to load the skill ID into r1 for SkillTester, but this works fine.

hey what about icons, descriptions, etc.?

I mean you don’t really need those, they’re just aesthetics. @Sme goes over that part here, and you should probably read the rest of the guide, too.

Optimizations & Convention

Summary

There are several places in this guide where I have intentionally written poor code that lacks optimizations in order to make it easier for beginners to understand. If you want help with your code, don’t worry - others will point out poor code to you. But if you want to share the code (eg. to add skills to SkillSys master), it is expected that you make an attempt to have readable, fast code. For example, IsUnitPlayer could be optimized a lot (and doesn’t even need to be a separate function).

IsUnitPlayer: 
@ given r0 = unit struct, return 0 if not a player
.equ DeploymentByte, 0xB
ldrb r1, [r0, #DeploymentByte] 
lsr r0, r1, #6 @ allegiance only 
mvn r0, r0 @ turn 0 into non-zero and vice versa
bx lr

We didn’t actually need r4-r7, so pushing / popping them wastes a few cycles. (Around 10 - approx. 280,000 make a frame.) We didn’t use bl, blh / .short 0xf800, or any other calls to other functions, so we didn’t need to push/pop lr either. No need to branch either!

Some tips:

  • Don’t push/pop registers you don’t use.
  • pop r0 and bx to r0 instead of r1 if you are not returning a value in r0.
  • Comment your code!
  • Create functions to call within your code

There are many other ways to make small optimizations that I’m sure you’ll learn over time. But for now, I hope this has helped with learning how to delve into asm and make some basic skills! Good luck!

4 Likes