I've googled out for books for an entire day and all of the books that use nasm provide code samples for either linux or 32 bit programming on windows. |
The thing is that you're working at the intersection of three separate systems.
1. On one side you have the assembler itself. What's its syntax? How do you tell it how to lay out data in the binary? What output formats does it provide and which are useful to your?
2. On another side you have the operating system. How do you interact with it at a low level? What are the calling conventions? How do you make system calls? What binary format does it use?
3. On the last side you have the CPU. What are its modes? What instructions does it provide and precisely how do they modify its state? What things do you need to look out for with regards to, say, alignment, ordering of parallel operations, performance, etc.?
Which of these is "learning Assembly"? I would argue only #3. However, although CPU manufacturer specify their own syntax for the assemblers they make for their CPUs, you may find that for one reason or another you need to use someone else's assembler which works differently, so you still need #1. And unless you're writing your own OS, if you can't talk to the system you won't be able to do much (assuming you're writing a
lot of Assembly. Most people nowadays prefer to write only small parts of their programs that don't interact with the OS directly), so you can't skip #2.
So what's the problem? A book that could cover all three thoroughly would be so huge it would be irrelevant by the time it was finished. Most people learn like this:
1. They get experience working in C or C++ and learn the low level details of what happens when, for example, they read from a file, and generally how their OS works at a low level.
2. While debugging their code, they slowly learn
an Assembly syntax (which one doesn't matter) in order to read disassemblies and the semantics of some instructions. They start to learn the basics of how the CPU works.
3. Eventually they need or want to write some Assembly code. At this point they know enough of how the CPU works that they can more or less see how to structure the code and which instructions they'll need, and just need to pick an assembler that fits into their build system, and they learn the sytax of that assembler.
4. Finally, if they need something deeper, they can consult any of the multitude of references and cheatsheets for their CPU when they're writing something more tricky. See for example the Intel manuals or the
X86 Opcode and Instruction Reference:
https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html
http://ref.x86asm.net/index.html
Again, there's no book that condenses all of this and its infinite variations because it's just too much. You'll only find texts that cover some of the above and expect you to already know the missing parts or to be able to fill it in yourself.