Jeff Duntemann's Contrapositive Diary Rotating Header Image

My Assembly Language Books

Way back in 1988, an acquisitions editor at Chicago-area book publisher Scott, Foresman (now part of Harper Collins) asked me if there was room in the technical book space for a new series focused on Intel assembly language–and if so, would I like to be series editor? I was unemployed and the money sounded good so I agreed. By 1990 I had acquired two new books and wrote one myself. All were devoted to assembly language under DOS using the x86 CPUs, including the IBM PC’s 8088.

Which brings us to my Assembly Language from Square One. I had done quite a bit of thinking on what would constitute a beginner’s book on assembly. It sounds a little nuts, even today, but my goal was to teach assembly language as the reader’s first programming language, and make it accessible to people who barely understood what a computer actually is.

How does it work? I start at the beginning, the real beginning, and explain what computers are and what they do. Assembly language must take the hardware into account, so I talk at length about the Intel/AMD hardware architecture. And when I finally get down to teaching assembly language itself, the emphasis is on memory addressing. In assembly language, if you know where your operands are, you’re three quarters of the way to anywhere else you might want to go.

This is a radically different approach from most “intro” assembly books, which begin by teaching you the MOV instruction, and then perhaps the ADD instruction, with little or no discussion of the context in which assembly language instructions operate. This is dumb. Instructions are probably 35% of the trick in assembly language. 50% is memory addressing, and the remaining 15% is odds’n’ends.

As good and as popular as that series was, fate was against us: In 1990, Harper Collins acquired Scott, Foresman. Practically the first thing that Harper did after the acquisition was put Scott, Foresman’s entire computer trade line out of print and revert rights.

So there I stood, having just founded a new publishing company to create a glossy magazine for programmers, with an unpublished book in my hands and no clear idea what to do with it. We had been doing some book packaging for John Wiley & Sons, and our connections there led to one of Wiley’s acquisitions editors. He liked the book, and offered me a lucrative contract–the only catch being I had to change the title. The reasons for this have to do with retail channel orders and returns and I won’t bore you with it. Bottom line: I was now revising the book as Assembly Language Step-by-Step. I added some new material, but for the most part it was the same book, and when it appeared in 1992, sold very well.

I’m not sure who told me, nor whether it’s really true, but from what I recall the book’s cover image was lost or came out badly, and they needed art in a hurry. So they used my author photo instead. No complaints, though it reminds me how young I looked in 1992, heh.

Come 1998, our publishing company (The Coriolis Group) was successful and we were making good money. I had discovered Linux in the mid 1990s and found it fascinating enough so that when a (different) acquisitions editor asked for a revision, I got ambitious and suggested a book treating both DOS and Linux assembly language. Like the book’s original concept, this was also a little nuts. The DOS section of the book was mostly unchanged. The Linux material was confined to a couple of chapters at the end. I wasn’t happy with that, but there was a hard limit of 600 pages set by Wiley. The book came in at 620 pages, and appeared in 2000. Like the others, it sold extremely well.

This is a good place to explain the edition numbers of my assembly book. I consider the Scott, Foresman title the first edition. But the 1992 edition was Wiley’s first edition, so it was also tagged as the first edition, even though on my personal timeline, it was the second. I consider the Wiley second edition the third, and so on. It says “4th edition” on the cover of x64 Assembly Language Step-by-Step. In my mind it remains the fifth.

Assembly Language Step By StepWiley (again, a different acquisitions editor) asked for a revision in 2007. They suggested that DOS was obsolete (which I heartily agreed) and the book should now focus entirely on Linux. That was good news, but it meant a great deal more rewriting and lots of new material. Smoke was coming out of my ears, but the 3rd (Wiley) edition appeared in 2009. (At left.)

There were glitches. Some of the free software I cited heavily in the book was withdrawn from the Linux repositories scant months after the book’s publication. This damaged the book’s reputation, though I doubt anyone blamed the book when the Insight debugger went away. I offered Wiley a revision a couple of times in the teens, and each time they politely turned it down. It wasn’t until April 2023 that yet another Wiley acquisitions editor asked for a revision. This time, the idea was to focus on 64-bit programming. The Intel/AMD instruction set had changed, as had the registers and numerous other things. Although I describe some of the earlier architectures for context, the meat of the 4th Edition is all about x64 Linux running in Long Mode.

It took most of 2022 and some of 2023 to complete the revision, but by then I knew the drill and the book finally appeared on October 24, 2023. Taking all the editions into account (including the original Scott, Foresman title) the book had been in print for 33 years before the Wiley 4th edition appeared. My guess is that the 4th Edition will be in print for a long time. (See my note below on the 128-bit question.)

Where to Buy It

Amazon was taking pre-orders a couple of months before the book was formally released. So Amazon is the obvious source. To what extent it will be available in bookstores I have no idea. The book was issued in both hardcover and ebook format. For Amazon’s order pages, click on the edition you’re interested in buying:


Ebook (Kindle format)

Download the Listings Archive

As with all my earlier editions, I created a .zip file containing all the source code listings and associated files for this book. When you extract the contents of the .zip archive, it creates a hierarchy by chapter and program name. (Note that not all chapters have listings, especially the early ones.) Every .asm file must have its own folder. The reason for this should be obvious: Under Linux, every makefile must be named “makefile” or the make utility will not recognize it. So you can’t just pour all the book’s listings into one big folder, because every project that uses make has its own unique makefile, all with the same name.

Just click here to download the listings archive.

Download the Table of Contents

A PDF file of the table of contents exactly as it appears in the book can be downloaded here.

Download a Sample Chapter

To give you a flavor for how the book is written, I’ve obtained a PDF of a sample chapter from the publisher. Click here to download it.

A quick note on the downloads here, especially to old timers: You can’t obtain the files using an FTP client, for security reasons. You have to use the download machinery in a Web browser. Click the links in a browser and you’ll get them.

Will There Ever Be an X128 Architecture?

I get asked this a lot. Never say never, I guess, but in this case I’d say no. One of the main reasons the industry adopted x64 as quickly as it did is that 32-bit x86 can only address 4 gigabytes of RAM without using all kinds of scurvy tricks. 4 gigs is all you get with 32 address lines. 64 address lines can address 2×10 to the 19th power memory locations, which is a substantial fraction of the number of stars in the observable universe. The “4 gigabyte barrier” is gone forever.

The other reason is the fact that nearly all modern Intel/AMD chips have a math coprocessor already on the same die as the CPU. The AVX-512 math subsystem not only has 128-bit registers, it has 256-bit and 512-bit registers as well. Programmers no longer have to do high-precision math using the general-purpose registers.


P.18. Table 2.4. Multiple problems; the table below replaces Table 2.4 entirely.

P. 22. Table 2.6. Multiple problems; the table below replaces Table 2.6 entirely.

P. 29: At the right-hand end of the 5th row of additions, the addition 7+8 is shown as 0EH. It should be 0FH. All the other additions on that row are correct. That last item is a typo.

P. 30: In the top row of hex addition examples, the example A+A should be D+A. Simple typo.

P. 70: First paragraph under the header “Promotion to Kernel”: I spelled Linus Torvald’s first name as “Linux.” Typo, probably by typing the word “Linux” so much. I doubt I’m the only one who’s made that mistake.

P. 75: Almost at the center of the page: “64 KB64 KB” should be “64 KB”. Not sure how this one happened.

P. 127: The line:
testerr.asm: 20: symbol ‘evx’ is undefined
should be:
testerr.asm: 20: symbol ‘rvx’ is undefined
This was a holdover from the previous 32-bit edition.

P. 166: the line:
ld -o eatsyscall.o eatsyscall
should be:
ld -o eatsyscall eatsyscall.o

The two filenames were reversed in order.

P. 204, code near the top:
The code is technically correct. However, when you use DIV with 64-bit registers, make sure you have no “garbage” values in RDX, as the dividend is passed to DIV in RDX:RAX. If there’s a random value in RDX, your dividend will not be what you expect, and the DIV operation itself may crash your program. This is true for 16-bit and 32-bit divisions as well, both of which expect the “high” half of the dividend in the DX or EDX registers as appropriate. Unless your dividend is a big enough value to require placing it in two registers, zero the high register first. Whether you put a value in the high register or not, the CPU takes the high register into account when executing DIV.

P. 218, bottom:
The names of the variables in the definitions must each be followed by a colon.