It's funny to me how much grief x86 assembly generates when compared to RISC here, because I have the opposite problem when delinking code back into object files.
For this use-case, x86 is really easy to analyze whereas MIPS has been a nightmare to pull off. This is because all I mostly care about are references to code and data. x86 has pointer-sized immediate constants and MIPS has split HI16/LO16 relocation pairs, which leads to all sorts of trouble with register usage graphs, code flow and branch delay instructions.
That should not be constructed as praise on my end for x86.
Yes, x86 is weird but the variable-length instructions are actually nice and easy to understand, once they're unpacked to text form anyway. The problem with them is they're insecure, because you can hide instructions in the middle of other instructions.
I think the biggest thing you learn in x86 assembly vs C is that signed/unsignedness becomes a property of the operation instead of the type.
It would be cool if you could use flags, which is easy/easier on some architectures like PPC/armv7, but x86 overwrites them too easily so it's too hard to use their values.
For this use-case, x86 is really easy to analyze whereas MIPS has been a nightmare to pull off. This is because all I mostly care about are references to code and data. x86 has pointer-sized immediate constants and MIPS has split HI16/LO16 relocation pairs, which leads to all sorts of trouble with register usage graphs, code flow and branch delay instructions.
That should not be constructed as praise on my end for x86.