I started programming in the assembly about two months ago, and so far everything has gone very well. Let me give you a short summary of what I have learned so far.
Syntax
There are two main syntax for building x86: Intel and AT & T. For each, there are pros and cons. Intel syntax seems to be used only for x86-based processors, while AT & T syntax is used for several different architectures (e.g. ARM). If you look at the source code of OpenBLAS , you will see that they use AT & T syntax for several different architectures. However, many people think that Intel syntax is more readable. So far, I have programmed using Intel syntax, but I know how to read AT & T syntax for the most part.
Installers
You can use the built-in assembly with GCC, but not with 64-bit MSVC. So far, I have not worried about the built-in assembly. You can select several assemblers, for example: MASM , NASM , YASM , FASM and GAS . MASM uses only Intel syntax and is used only for Windows, as far as I understand (I do not think that it can be ELF object files for Linux). NASM also uses only Intel syntax, but can create several different object files, for example. for Windows and Linux. YASM, as far as I can tell, is NASM for the most part, but also supports AT & T syntax. FASM uses Intel syntax and can create several different object files, but it is slightly different from NASM and YASM. I haven't used FASM yet, but it looks alluring. GAS uses AT & T syntax (although Intel syntax can be used) and is actually used when compiling with GCC. GCC produces the assembly, which is sent to GAZ.
It is important to understand that each assembler has only a dialect, so you cannot expect that the code written in MASM is necessarily assembled out of the box in NASM. NASM and YASM are mostly compatible, as I understand it.
Which assembler should you choose? I have used NASM so far.
Conventions and C references
The best source of training for me so far has been GCC. Write the code in C, and then look at the assembly. For example, if you have a simple function foo , you can do
gcc -O3 -S foo.c
then look at the file foo.s or you can use objdump
gcc -O3 -c foo.c objdump -d foo.o
You must know the function that invokes your OS conventions . The calling conventions are different for 32-bit code and 64-bit code. For Windows and Linux, they are the same for 32-bit code, but different for 64-bit code. So far, I just wrote build code with NASM for Linux 64-bit.
Many assembly issues in SO seem to be related to writing entire functions in the assembly, including data input and output. I do not think this is necessary. Let C take care of input and output. You can see an example of this question . I gave NASM code and C code, and also explained how to compile, compile and link them. This was one of the first things I wrote in the x86 assembly. In this question I had a function
float triad(float *x, float *y, float *z, const int n);
Linux x86-64 calling conventions (or rather System V AMD64 ABI) pass the first parameter in the rdi register, the second in rsi , and the third in rdx . So, in this case rdi=x, rsi=y, rdx=n .
Once you get the calling conventions and can link your object files to the assembly with C, you will find working with the assembly much easier.
Finally, the second best learning source for me was the Agner Fog Optimizing Assembly manual . There are many good tips in the first part of the beginner's guide. And as soon as you get some experience, there is a lot of good information in the later part of the manual.