C is the &#x27;portable assembly&#x27; of the world. I find it easiest when learning some CPU architecture to compile very simple C programs and then see what the resulting assembly looks like.<p>Some questions I look at:<p>* When I cast a float to an int, what actually happens behind the scenes? Sometimes there are floating point instructions that get generated. Sometimes the CPU doesn&#x27;t have floating points, so it emits calls to a &#x27;float2int()&#x27; function that implements it in software.<p>* What is the calling convention? Just write a function with 1,2,3,4 and 20 arguments and do something like add them together. Then see how the resulting function handles those arguments.<p>* What do some simple array accesses or pointer arithmetic generate?<p>* How are large structs passed to functions at higher optimization levels?<p>* If I write a loop to compute a dot product, do higher optimization levels emit vectorized instructions?<p>You can actually go pretty far with this. Just use tools like objdump or gcc to probe or create object files, and then start writing assembly once you understand what C code you&#x27;d write and what it would compile down to.