Imho ist x86 Assembler nicht besonders kompliziert. Es ist kompliziert ein "ganzes Programm" darin zu schreiben, aber die Instruktionen sind nicht besonders schwer zu verstehen. Du musst wissen, welche Register du zur Verfügung hast, welche Instruktionen es gibt und wie du auf die Hardware oder auf Betriebssystem/BIOS Funktionen zugreifen kannst.
An Registern wären da die GPRs (General Purpose Registers) EAX, EBX, ECX, EDX, ESI und EDI zu nennen, welche wie der Name schon sagt "normale" Daten (Integer, jedoch keine Fließkommazahlen oder spezielle Flags) enthalten. Sie werden durch Instruktionen wie MOV, ADD, SUB etc. manipuliert. Die meisten Instruktionen können neben Registern auch auf Speicheraddressen in der Form [basis + index * scale + disp] zugreifen, wobei basis und index GPRs sind, scale entweder 0, 1, 2 oder 4 ist und disp eine Integerkonstante ist.
Bespiel:
mov eax, [ebx + ecx * 4 + 1024]
Hier wird zuerst ebx + ecx * 4 + 1024 berechnet und der 32 Bit Wert der bei dieser Addresse steht in eax geschrieben. Die [ ] markieren in NASM Speicherzugriffe. Da wir im 32 Bit Protected Mode sind manipuliert die Instruktion standardmässig 32 Bit Daten.
Um auf die Hardware zuzugreifen werden die Instruktionen "IN" bzw. "OUT" benutzt. Manche Hardwarekomponenten lassen sich auch über bestimmte Speicherbereiche direkt ansprechen. (Beispiel: Der Framebuffer der VGA Karte im Textmodus liegt bei Speicheraddresse 0xB8000. Das OS kann einfach mit "mov [0xB8000], irgentwas" auf die VGA Karte zugreifen.
Das BIOS wirst du im Realmode auf jeden Fall brauchen, auch wenn du so schnell wie möglich in den PM (Protected Mode) schalten möchtest (weil du nur dort vernünftig mit C++ arbeiten kannst und genügend Speicher zur Verfügung hast). Verwende GRUB als Bootloader um unnötige Assemblerprogrammierung zu umgehen. Falls du deinen Bootloader dennoch selber schreiben möchtest, musst du auf BIOS Funktionen zurückgreifen. Sie werden fast immer über Interrupts aufgerufen. (=> "INT" Instruktion)
Ansonsten solltest du dir einfach mal einen kleinen C/C++ Kernel ansehen, der bereits Interrupts und Schreiben von Buchstaben auf den Screen unterstützt. Ich habe meine Assembler Grundlagen hauptsächlich durch das Lesen von Beispielcode erlernt. Wenn du in C/C++ schreibst wirst du Assembler nur für die Kommunikation mit der Hardware und für einige Funktionenstubs brauchen, die spezielle Prolog und Epilog Sequenzen haben müssen. (Interrupthandler müssen mit IRET statt normalem RET zum Caller zurückkehren, außerdem müssen sie oft auch alle Register sichern, damit der Caller nicht eine veränderte Situation vorfindet etc. für fast alles andere kommst du mit einigen Zeilen Inlineassembler in deinem Code aus.)
Wenn du wirklich ein ASM Tutorial brauchst, kannst du dir das hier ansehen:
http://maven.smith.edu/~thiebaut/ArtOfAssembly/artofasm.htmlEine Referenz aller BIOS-Interrupts gibts hier:
http://www.ctyme.com/intr/int.htmDas NASM Manual weiß alles über die Syntax von NASM und enthält sogar eine Instruction-Referenz:
http://alien.dowling.edu/~rohit/nasmdoc0.htmlAnsonsten steht alles wissenswerte in den Intel und AMD Docs, für die ich aber gerade keinen Link habe.