top | item 38203553

The Netwide Assembler (NASM)

139 points| gjvc | 2 years ago |nasm.us | reply

55 comments

order
[+] jrockway|2 years ago|reply
I have a kind of off-topic NASM story. I think I was using it circa 2004 for a class, and was taking another class that required us to find 10 exploitable security holes in existing software. (This was DJB's "Unix Security Holes" class. Best class I ever took.) NASM was the first place I looked (my thought process was, it takes untrusted input and it's written in C), and indeed I found one: https://lists.debian.org/debian-security-announce/2005/msg00...

Incidentally, the other holes I found for that class were various XSS vulnerabilities in our course registration software. The administration was furious with me (I didn't exploit them, only proved that they existed), and banned me from using any computers at the University. DJB stuck up for me, though, and the vendor sent me a new iPod as a thank you. It was pretty stressful for a first-year student in 2004 though.

My parents really didn't want me being involved in any security-related fields, so I ended up not really touching it again. My take these days is that security is a subset of correctness; design for security, and make sure you implement it correctly, just like you do for any other feature. I also write a LOT of fuzz tests ;) But yeah, NASM was the beginning and end of my software security career, which I still find kind of amusing.

[+] sneed_chucker|2 years ago|reply
Thanks for reminding me again just how thankless vulnerability research and computer security in general is.
[+] pacman128|2 years ago|reply
Nice to see NASM is still going strong. I used this for a class I taught back in the 90's. The class supported both Windows and Linux (but most students used Windows) and NASM supported both and was free.

I ended up creating my own free online textbook for the course. It's sorta out of date now since it was for 32-bit processors.

[+] tuckerpo|2 years ago|reply
I've used nasm in industry as late as 4 years ago to assemble some bootloader code. It's great.
[+] voakbasda|2 years ago|reply
Maybe out of date for the desktop, but 32-bit systems continue to be relevant in embedded systems.
[+] AYoung010|2 years ago|reply
Still in use academically too - we used it in my compilers class last year.
[+] ibobev|2 years ago|reply
Could you provide a link to the book?
[+] larodi|2 years ago|reply
Wonder why Tatham is not an ACM fellow or something like it yet. Some very widely used code came from under his fingers.
[+] jcalvinowens|2 years ago|reply
One of my little pet projects is a Linux webserver written in NASM: https://github.com/jcalvinowens/asmhttpd
[+] flykespice|2 years ago|reply
Damn, that is really impressive I like how you keep it very compact but very readable, and your use of macros for the syscalls is very pleasing
[+] ilovetypescript|2 years ago|reply
Thanks for inspiration! I’ve been learning x86 asm and now i’m going to put my skills to the test.
[+] miki123211|2 years ago|reply
Why would anybody use this over the assembler shipped with their compiler?

This might make sense if your project is written entirely in assembly, but does anybody even do that nowadays? For projects that are mostly in C/C++ with bits of assembly here and there, it's yet one more dependency your users have to install.

[+] dfox|2 years ago|reply
NASM has a logical and sane syntax that is both readable and maps directly to the generated instructions, in other words it is designed to be written by hand, not as an convenient intermediate format for the compiler to generate.

Contrast that to typical AT&T-syntax x86 assembly with bunch of meaningless punctuation and complex addressing modes represented by bunch of comma separated numbers. And with MASM that needs bunch of boilerplate and noise words, because the syntax is motivated by what was required to produce real-mode 16b object files.

[+] x2rj|2 years ago|reply
If you write cross platform software, you might want MSVC on Windows and gcc on linux and their assemblers masm and gas have very different syntax. nasm outputs object files for both directly. Also the syntax in the context of especially macros is often a little better.
[+] jwr|2 years ago|reply
Trust me, at least on Intel, you do not want to write assembly inside your C/C++ code, unless it's just a couple of lines. The usual AT&T syntax will drive you nuts, and the additional syntax for embedding assembly only adds to the misery.

For any reasonable amounts (say, you want a function or several) of assembly, you want Intel syntax and standalone assembly files.

NASM is a great tool, although YASM should also be mentioned: https://yasm.tortall.net — YASM is what I used when I optimized an H.264 decoder for Intel-compatible CPUs way back in 2005 or so.

[+] DonaldPShimoda|2 years ago|reply
Perhaps a small use case, but nasm is used in UMD's compilers course (https://www.cs.umd.edu/class/fall2023/cmsc430/).

And while that in itself is maybe not particularly exciting, I think the underlying point is more that assemblers like nasm allow for the implementation of toolchains like this, where you have some assembly with some C code. While not common, I'm sure cases like this are also not exceedingly rare.

[+] benj111|2 years ago|reply
nasm has better goto labels you can use sublabels within a block that don't need to be globally unique.

The data generation stuff is better aswell.

This was a while ago, and I could have missed these features else where, but that's why I ended up at nasm.

Yes, if youre just doing a bit of assembly, use whatever, but if you're doing a bigger project in assembly, nasm is optimised for that, rather than dealing with the output of a compiler.

[+] wg0|2 years ago|reply
We were taught NASM as part of a course and I'm so much accustomed to it's beautiful syntax.

Is it less capable than MASM? Don't have a reason to believe so because there's one to one correspondence between what you write and what's gets executed.

[+] mobilio|2 years ago|reply
MASM is Microsoft product and can produce .COM and .EXE files (DOS, OS/2, Win16, Win32 and Win64) plus DLLs.

NASM supporting bin, ith, srec, obj (OMF), win32, win64, coff, macho32, macho64, elf32, elf64, elfx32, a.out, aoutb, as86 and dbg.

With minimal changes MASM code can be converted to NASM.

[+] torusle|2 years ago|reply
I wrote thousands lines of assembler for NASM. It was such a nice update to the good old turbo assembler back in the 90th.
[+] mobilio|2 years ago|reply
Same here... i come also from TASM
[+] pjmlp|2 years ago|reply
As Borland fanboy, TASM was already quite cool, the only thing I missed was MASM being more high level with its macro capabilities, but by time I got to play with MASM, I was already into Windows 3.x world.
[+] paraiuspau|2 years ago|reply
Good memories. Thank you zsKnight, wherever you are.
[+] kreig|2 years ago|reply
Same thing came to my mind, when zsnes became open source in early 2000s and we were able to explore its thousand of ASM lines in NASM dialect.
[+] adevopsguy|2 years ago|reply
I have been using NASM in my spare time recently because “learning” assembly is an itch I always had. I’m having so much fun. Cool to see it posted here.
[+] ilovetypescript|2 years ago|reply
Same here! NASM really gets me out of comfort zone but i’m a good way.
[+] susam|2 years ago|reply
I began learning computer programming with Logo [1], then BASIC, then C, Lisp, etc. However, somewhere along the way, growing dissatisfied with not knowing exactly what's going on under the hood, I began descending down the stack. That journey led me to learning about the CPU, using assemblers, as well as loading instructions in hexadecimal format into a memory by pushing buttons on a 8086 trainer kit. At one point, I also designed my own Mano Machine in VHDL which I then synthesised and tested on a Xilinx CPLD kit [2].

The last one was the most fun. It was very rewarding to see the abstract concepts presented in books come alive in the form of a working machine that could fetch, decode, and execute instructions from a memory. The memory was designed in VHDL too and implemented on the same Xilinx CPLD kit. Loading instructions into the memory required me to push DIP switches (one switch for each bit). A far cry from the comfort of Emacs running atop a modern operating system!

Those two adventures lied on opposite ends of a spectrum. There was the luxury of high level languages and tooling at one end. On the other end, there was the hands-on ritual of loading each bit of instruction, accomplished through the deliberate act of manipulating DIP switches. Such a laborious experience prompts a profound awareness that ultimately all software executes on physical matter.

Nestled in between these two extremes, there was a sweet spot involving assemblers. The first assembler I stumbled upon was the "A" command of DEBUG.EXE [2] of MS-DOS. The features were very minimalist and the tool was a bit more than an assembler. This humble debugger allowed me to peek into interrupt vector tables, inspect the content of ROM, learn how MS-DOS boots from scratch, etc. I later did come across GNU as, TASM, NASM, etc. which made me appreciate the number of bookkeeping problems a proper assembler solves. No more recalculating all the offsets for the jump and call instructions after every refactoring of the program!

These days, I work very high up in the stack where there are numerous layers of technology between what I type and what the physical machine executes. But I do fondly remember the days when armed with an assembler, some knowledge of the CPU and the computer architecture, we could plunge into the depths of the system, unravelling its intricacies to our heart's content.

[1] https://susam.net/blog/fd-100.html

[2] https://github.com/susam/mano-cpu

[3] https://susam.net/blog/programming-with-dos-debugger.html

[+] Multicomp|2 years ago|reply
TL;DR: I want to tinker with one assembler, which is better for tinkering, NASM or FASM?

I am looking to one day learn assembly (x86, x86-64 and potentially ARM) simply for tinkering hobby purposes, to prove I learned something watching all those Ben Eater TTL youtube videos and try my hand at logic design and creating toy programs that are as close to the metal as possible, just to say I can do it.

But part of the trick is not knowing where to start. There's MASM which appeals to me as a higher level language user in that you create those macros and use them in various places, and there's NASM and FASM which I like the idea of since they seem to be more portable to both Windows and Linux. I doubt I can write an assembly program and run it on an old android smartphone, so I'll leave that aside here.

[+] anta40|2 years ago|reply
Depends on your specific purpose/environment, perhaps. If you want ARM, FASM can also do that: https://arm.flatassembler.net/

I mostly use NASM for x86-based OS kernel experiment because sadly FASM won't run on recent Macs, since it's written in 32 bit asm.

[+] uticus|2 years ago|reply
This is why C is a high level language (and portable)
[+] flohofwoe|2 years ago|reply
A good macro assembler allows to write code on an abstraction level that's not much different from C though ;)

What actually makes C a high-level language isn't the language, but the optimizer passes in modern C compilers.