- Write a program that just returns, or halts;
- Write a program that prints something or blinks an LED;
- Print numbers 1-10;
- Handle some input, using function calls.
- Write some data structure (binary tree or hash table). Or maybe get an MMU working, and handle a system trap.
... working your way up to writing a context switch handler, for a coroutine or threading system, of course :-)
... at that point, you're off to the races. Mostly I try to get the toolchain a debugger working reliably in the first step, and everything just builds on that.
At least one guy in our class used Linux tools to work through the chapters we studied, although the instructions are focused on VS.
[ed: Initial hn discussion should be relevant to this thread: Say hello to x64 Assembly, part 1 (0xax.blogspot.com) https://news.ycombinator.com/item?id=8245581
(The posts are posted on the blogspot blog, but if I'm not mistaken they're all there in full, in the github repo) ]
The layer between them is really razor thin — by learning a few C idioms (function prologue/epilogue and the stack frames, argument passing, etc.) you'd be well on your way. You also need to start writing simple asm code as soon possible; only reading about it won't make it stick.