I'm learning x86 assembly because I want to write a simple operating system -- and a simple operating system written from scratch requires a boot loader.
It feels futile. In the beginning, I spent a predominate portion of my time glaring at singular instructions, experiencing a complete loss for thought, let alone language to describe my mental state. I built a simple but functional disassembler for the Intel 8080 in C with hopes of learning assembly through the process. I suppose this small project brought me a step closer to assembly, but I certainly didn't learn it by any stretch of the imagination. After all, I wrote very little assembly for this project -- only simple proof of concepts. However, I think it helped me better understand assembly holistically -- in the way a medical doctor may be able to explain the body's musculature but cannot use it like a fine-tuned athlete. Although, I am neither so knowledgeable nor so skilled with assembly, so the metaphor is hardly apt.
After building a disassembler, I spent a majority of my time copying assembly from the internet and various books, attempting to interpret it. I worked through several chapters of Beginning x64 Assembly Programming: From Novice to AVX Professional while heavily referencing Stack Overflow and NASM documentation. Though I skipped many of the chapters on SIMD and floating-point arithmetic, the book helped tremendously overall.
Within a handful of days, I wrote a function to print numbers in binary as an exercise from the book. It's the closest I had been to writing assembly from scratch at that point; and though the function worked, I found it quite troublesome and poorly written on my part. Nonetheless, I was pleased enough with it to continue.
Two or so assembly-filled days following the binary output function, I was able to write the beginnings of a function that prints values in hexadecimal instead. At that stage, it printed the decimal values of the hexadecimal digits: 2 as 2 and b as 11 and so on. The values themselves were correct though. They were, however, backwards because I began from the least significant bit rather than the most significant bit, thus printing from least significant to most significant -- but I'm convinced, albeit steeped in ignorance, that little-endian should not be read any more than strictly necessary. It's ironic considering I'm writing x86 assembly.
Later that day, I was able to output values in hexadecimal by leaning on printf's "%h", but the BIOS sadly isn't so kind as to provide this functionality.
In an additional day, I finished the function at the BIOS level. It's a hack. It's no beautiful solution, but it works. For now, I'm content with that. I want to continue with the functionality of boot loader. I'm ready to continue iterating upon that aspect of it rather than its so-called debugging utilities.
As I mentioned, it feels futile -- progress is slow -- but I'm drawn to it like a moth to a flame. I only hope to avoid the burn (out).