Any local variable will be created in the stack, or a register would be used instead.
Try this:
u8 i = 5;
set_attr (pokemon, attr_HP, &i);
"i" would be created in the stack, and the SP would be passed into set_attr.
In almost all situations, programming in C is superior to programming in ASM. However, I should note that the ASM instructions generated by GCC/DevkitARM/whatever_you're_using, will always not be as efficient as hand written ASM will be. A competent human writing ASM will, in some cases, write code more efficiently than the compiler generated code. However, the benefits of writing the exact code in ASM isn't exactly worth it. Consider this: Would you rather spend 10 mins writing C code which executes 100 CPU cycles slower? Or spend 30 minutes writing ASM code which executes 100 CPU cycles faster? 100 CPU cycles is very negligible depending on the nature of your code and where it's used. In 99% of cases, we wouldn't care about the slight efficiency drop. The GBA's processor has a clock speed of 16.78Mhz. That means every second it has the potential to do 16780000 cpu cycles. Saving 100 cycles and spending 20 minutes does absolutely nothing. Something like this would only matter in an area like the main loop, which is executed extremely frequently.