https://www.youtube.com/watch?v=FolqIgQRtl0
Its mostly setting watches and breakpoints in the emulator, not digging through code. My mind was blown the first time I watched it.
Starting with no experience, I wrote a program to dump level images straight from a ROM:
I have never owned one, but i think gamesharks and others work similarly.
Here's one of the main pages I used as a reference at the time: http://doc.kodewerx.org/hacking_nds.html Even without ASM, you could still write to arbitrary memory addresses, jump around with conditionals, patch, copy memory, and all sorts of things. The linked page also touches on the basics of ARM/THUMB ASM tinkering. I seem to have lost my notes, so this is all I can get you :(
Two examples from Super Mario World (which loves this technique):
• You can avoid dying from running out of time in SMW, by simply getting a power-up right as the level timer reaches zero. The level timer just changes the Mario sprite's animation to STATE_DYING (once, when transitioning from 1 to 0); so if you can get the sprite to play a different animation, the game forget that the player was supposed to be dead.
• The "null sprite" glitch: Yoshi 'carries around' enemies in his mouth by just 1. marking the enemy sprite as invisible and intangible, and then 2. storing a pointer to said enemy sprite. If you can get that sprite to unload from OAM memory and get something else to take its place, then when Yoshi goes to spit the enemy out, he'll instead spit out whatever random garbage is now at the OAM location referenced by the pointer.