There's two main kinds of pokemon data: pokemon structs and battle structs. The former represents a pokemon in your party, and has all of its persistent information; the latter represents it in battle and has most of its battle-pertinent information. The Pokemon struct only stores a single bit for ability, indicating which of its species' abilities it has; battle structs store the ability byte outright, and change to accommodate effects like Trace and Skill Swap. Usually, you want the latter struct- it's documented in the old JPAN thread I was talking about.
A special case is a branch in code for one specific case, and is how the majority of abilities are handled. For example, there's some code in the game that if decompiled would look something like:
if(pokemon.ability == ABIL_NATURALCURE)
pokemon.status = 0;
This is in opposition to the standardization you see with most moves, where Flamethrower has a 10% chance of inflicting burn because its battle script rolls against its proc rate, which is defined in a table.