Hmm. Had we been discussing most other systems and most other tutorials I would have say "so you want to find either injection/hooking points, the position of functions/sections of functions or space for your new code". Having now seen the cheat making and oddities there I am not so sure this is what you seek but in the absence of much else I will go with the above. If that is the standard tool than N64 hacking was more... agricultural than I feared. My main dalliances with MIPS tend to come when I am doing single instruction things on the playstation or compiling whatever which means I get to play with nice tools like http://www.romhacking.net/utilities/635/
. Unlike say the ARM7 and ARM9 instruction sets (differences but similar enough that you can use one on the other and it will work) I have no idea about the extent of the differences between R3000 of the PS1 and the R4200 of the N64 and it could be quite large.
Anyway you are pretty much then looking at tracing.
Going back to bullets in a gun.
You do the usual cheat thing and find that the number of bullets in a gun is stored at memory location [a]
Hurrah you can make a cheat for infinite ammo (assuming that is always the location of the bullets in a gun).
Being an assembly hacker you decide you want to take it a step further. You set what is called a breakpoint (maybe a watchpoint if you prefer that style of things) and when you next shoot a bullet the emulation will halt (at just shy of 94MHz that is still probably in the millions of operations per second) and up will pop a screen saying this instruction was either trying to subtract a value or set it depending upon certain things and where that instruction was found.
This instruction will either be in memory (fair enough, you get to repeat things) or in the ROM itself (always nice though maybe not the end of your road).
Now being an assembly hacker you have many paths available to you at all points, we often find this scares those new to assembly but not to programming but it is a fact of life and you get to deal with it. If you wanted infinite ammo you could then either break the set value or more likely go back a step or two and find the subtract number and change it to a set (though there is typically no such thing as set and to do that you use the MOV command). A warning at this stage -- though programs and programmers are taught to love functions sometimes it is not worth the penalty (though MIPS is quite odd here and where most other programmers are getting to be fast friends with the push and pop commands MIPS deals slightly differently if you want it to) and there can be many different sub commands and set value methods working on a given value, the traditional example given is to think of all the ways you can die in Mario (pit, enemy, time, poison mushroom, crushed behind a moving level....) and though the value may be a single location the amount of things that can and are designed to touch it may be higher. On the flip side and my favourite example is drawn from the N64 in the case of Goldeneye. Find a gameshark cheat for infinite life and turn it on. You can be shot all day but proper explosions might still kill you -- this is as the cheat can not hold your life high enough against as much damage as a proper explosion will do. Your assembly hack that negates the initial change has truly rendered you invincible though.
If your value was in the memory you get to repeat the trace until you find where that code came from in the ROM (though the promise of self modifying code is of great power it is still too dangerous for most people to use in practice so they do not). Though I guess you could make a cheat to change an instruction in memory, this is what many of the better DS cheats do as the binary is loaded into memory to even run.
Being an assembly hacker, and as such counted among the best of ROM hackers, you aspire to greater things still. Going back through the function you will see all sorts of things that deal with the firing of the weapon like recoil, damage, fire rate, accuracy.... congratulations you now have a recoilless, nuclear missile launching, rapid fire, sniper rifle. You may also notice that the values for those are loaded into memory from a table in the game (far better than having such a thing all in code) and you now have the basis for a weapons mod. Going back to the being shot part though you might also be able to negate the knockback/screen blurring effect.
Trace it even further back and you get to where it jumps to when it detects the button has been pressed and it only goes deeper.
To take it right back on topic though at each of those breakpoints it will tell you what instruction said to do it and where it is found. If it is memory you can try to see what put that in memory or try to grab that part of the memory and do a search in the ROM for it and if it is in the ROM you have your answer (give or take working a few steps forward or back to change exactly what you want). This sort of thing is also why they might have tried to teach you assembly when you learned programming as it does well when it comes to demonstrating why nested functions are often not ideal, why you may want to tone it down when it comes to storing everything in floats and other such things.
That covered injection/hooking after I say find the jump to that function or a part of the path and add your own jump, locating it comes as part of tracing and a place to put your own code is simply anywhere that has space. Finding said space may be easier said than done and you may have to trash something else, do your function, jump back and restore the original code, optimise later code to make it smaller to fit your instructions in or you might well simply get lucky and have a static section of memory that was never allocated or is never used.
Again your main problem is that the N64 debuggers fall far short of the really nice things we see with other systems or even the "everything is there but it might be a pain to use". n64js and Nemu seem to be your best bets but the main threads I found on the subject seem to be either quite outdated or from those are only skirted the peripheries of the N64 emulation world and there might be some as yet not widely known emulator with a debugger, I doubt it but I have seen stranger things happen.
That PDF... as far as primers on a non X86 architecture go it is one of the better ones I have seen, I do not know enough of the various flavours of MIPS and how it plays out across the consoles to say how relevant it would be to N64 vs some other MIPS device (it being geared more towards R2000 and R3000). For my taste it is a bit inclined towards the hand holding which I am not a fan of in programming tutorials but it is not unjustified, the appendices look quite nice as well.
I would still suggest http://www.plantation-productions.com/Webster/www.artofasm.com/index.html
along with whatever else I usually link (usually http://www.coranac.com/tonc/text/asm.htm
and finding a processor and/or hardware doc but I mainly deal in ARM stuff anyway). I usually prefer to go from various levels of electronics to general assembly, to general computer architecture, maybe a dash of FPGA type things and then lock it down/adapt it for the device (OK so this is basic assembly with fixed register size, I am not dealing with nested registers, I have no divide instruction on CPU but..., hardware floating point is single precision only, it is RISC so instructions tend not to exceed ? cycles, I have no SIMD stuff, immediate values are either a psuedo instruction or I have to generate them, memory access is only via a few commands rather than every instruction and on and on and on). I find this quite similar to learning a language mechanically (this is a verb, this is typical order of a sentence/noun-adjective....) in that you will often end up fairly proficient but you will miss many of the nuances until you encounter them for the first time and scratch your head for a while. on the flip side it does tend to allow you to transition between architectures somewhat more easily and if you are going to do something as backwards/esoteric as learning assembly in 2013 I figure you might as well have that. That said I have mad respect for those that do truly know an architecture and a system inside and out (I can make things work, they can make them sing).