NASM and FASM are really the only up-to-date and cross-platform capable assemblers. MASM is up to date, but Windows only. TASM is not up to date. Others appear to have been abandoned.
The differences:
NASM: Is written in C and generates object files. Requires a linker to produce executables. Slow, inefficient compilation. Has some syntax quirks. May be more flexible in some cases due to the multiple object formats available.
FASM: Written in FASM. Very fast compilation. Cleaner syntax, better debugging tools. Produces executables directly without a linker. Possibly limited due to smaller number of output formats, but likely good enough for most projects that would be written in pure asm anyway.
FASM looks like the best option to learn first and then move to NASM for any specific requirement that FASM cannot meet. The syntax is mostly compatible between the two, so porting code shouldn't be too much trouble in the worst case.
One possible other tool to consider is 'terse': http://www.terse.com/howdoes.htm
It's got a lot of issues, and you probably don't want to actually use it. It's unmaintained, proprietary, DOS only, and according the website, still distributed on a 3.5" floppy. But the syntax has a lot of appealing things about it. You can't actually read the real manual without buying the product, but a short lived open source clone "nega" used a very similar one: http://webcache.googleusercontent.com/search?q=cache:7E6Ddug...
It's easier to update an external assembler than the system assembler. A lot of distros don't ship with updated binutils so you can't reliably compile for newer CPU extensions on them.
Earlier versions of clang's integrated assembler (which clang uses instead of as) weren't fully compatible with as, e.g. no .intel_syntax support.
Different operating systems can have subtly different behavior, e.g. the ancient as that ships with OS X uses $name for macro parameters while most? other systems use \name. I think gcc on OS X is intentionally forgotten so everyone will switch to clang.
Cross platform x86 asm is a real headache no matter what. NASM/Yasm/fasm just make it less of one.
http://madscientistlabs.blogspot.ca/2013/07/gas-problems.htm...
# file:hello.s
#
# Translated to gas syntax.
# assemble with:
# as --64 -o hello.o hello.s
# link with:
# ld -o hellos hellos.o
#
# Modifications to original code considered trivial and to be
# public domain.
#
# Support intel syntal vs. ATT and don't use % before register names
.intel_syntax noprefix
.section .data
msg: .asciz "hello, world!\n"
.section .text
.global _start
_start:
# write syscal
mov rax, 1
# file descritor, standard output
mov rdi, 1
# message address
mov rsi, OFFSET FLAT:msg
# length of message
mov rdx, 14
# call write syscall
syscall
#
mov rax, 60
mov rdi, 0
syscall
Note the trailing new-line in the message (and length change from 13 to
14). For nasm: section .data
msg db "hello, world!",`\n`
;; Remember to use 14 for string length! # String is read only.
.section .rodata
msg: .asciz "hello, world!\n"
# Put string length in a variable instead
.set STR_SIZE, . - msg
# <snip>
mov rdx, STR_SIZEI don't count its fast compilation speed as much of a plus because you've got to write a heck of a lot of assembler before you'd ever notice much of a difference, I'd suspect.