Assembly Language Step-by-Step

Jeff Duntemann

Mentioned 8

The bestselling guide to assembly language-now updated and expanded to include coverage of Linux This new edition of the bestselling guide to assembly programming now covers DOS and Linux! The Second Edition begins with a highly accessible overview of the internal operations of the Intel-based PC and systematically covers all the steps involved in writing, testing, and debugging assembly programs. Expert author Jeff Duntemann then presents working example programs for both the DOS and Linux operating systems using the popular free assembler NASM. He also includes valuable information on how to use procedures and macros, plus rare explanations of assembly-level coding for Linux, all of which combine to offer a comprehensive look at the complexities of assembly programming for Intel processors. Providing you with the foundation to create executable assembly language programs, this book: * Explains how to use NASM-IDE, a simple program editor and assembly-oriented development environment * Details the most used elements of the 86-family instruction set * Teaches about DEBUG, the single most useful tool you have as an assembly language programmer * Examines the operations that machine instructions force the CPU to perform * Discusses the process of memory addressing * Covers coding for Linux The CD-ROM includes: * Net-Wide Assembler (NASM) for both DOS and Linux * NASM-IDE, a command shell and code editor for DOS * ALINK, a free linker for DOS programming * All program code examples from the book

More on

Mentioned in questions and answers.

Does anyone know any good NASM or FASM tutorials? I am trying to learn assembler but I can't seem to find any good resources on it.

There is e.g. Writing A Useful Program With NASM and of course the obvious

There are a couple of sample programs at

If you are looking for a more general introduction to assembly programming there is The Art of Assembly Programming and the wikipedia page on NASM references Assembly Language Step by Step by Jeff Duntemann.

I've always wanted to learn assembly, but there seems to be a jungle of assembly-related information out there that is difficult to interpret. I haven't just been able to google "learn assembly" and get going.

First, there are two types of syntax: Intel and AT&T. What's the difference? Why are there still two in use? When would I need to use one versus the other?

Second, there's a multitude of chips out there. Intel vs AMD, 32-bit versus 64-bit, x86 vs other architectures... even x86 is really a whole family of chips. So, how can I know whether the assembly I'm learning from a certain web page will work for my machine?

There exist even more variations (operating system even plays a role in determining how code will run.

So, the big question is, with all these variables, how can I know what type I should learn? What's most common? How is it possible for people to "know assembly" when there are all of these variations?

I once read Jeff Duntenmann's excellent "Assembly Language - Step by Step" a long time ago. It's probably the only book on 80x86 assembler for beginners that I've ever seen, and it's a very good one. A lot of stuff in it is somewhat out of date, I suppose, but programming in assembler on x86 itself is pretty passe for most things nowadays. But if you're looking to get started and you want a foundation, I think his book is where you want to be.

I'm interested in contributing to a Linux distro, but regarding the various distro's developer communities, I'm having a bit of trouble figuring out which one I'd most like to join.

What languages I know: C, C++, Lua, Python, and fairly familiar with Perl (though I wouldn't say I "know" it). In particular, I have very little experience with x86 assembly besides hacking stuff together for performance tweaks, though that will be partially rectified soon.

What I'm looking for: A community that provides plenty of opportunities for developers to work on various aspects of the distribution. To be honest I'm most interested in reading and working on the kernel source (in which case the distro doesn't matter), but it's pretty daunting and I figure getting into the Linux community and working with experienced Linux developers might give me a better idea of how to jump into the guts(let me know if this is bogus, or if you have any advice regarding that).


Which distro has the "best" developer community in terms of organization, people who are fun to work with, and opportunities to contribute?

I've read various "Contributing to XXX" pages and mailing lists for distros like Ubuntu, OpenSuse, Fedora, etc. but I'd rather get a more personal testament from an actual developer.

Unless you have a specific desire to learn the ins and outs of various packaging formats you would probably be better off contributing directly upstream to applications/libraries that you find interesting. While individual distributions often have a few management applications that are unique(ish) to them most core applications and libraries are shared between them.

As you have expressed an interest in guts it would make sense to stick to one of the main community distros (Fedora and Ubuntu/Debian) as the rest tend to be variations on a base distro. The other option is to choose a source based distribution which have a number of advantages to developers although you may find yourself spending a bit of time keeping your machine trim.

As I'm a developer I personally use Gentoo which gives me a number of things:

  • Rolling release: New versions of applications are generally available soon after release
  • Stable/Unstable mix: I can run stable core with bleeding edge on upstream packages I care about
  • Development ready: Any installed package is by default a "dev" package, the distinction between buildtime/runtime dependencies is blurred
  • Packaging is easy: If it's a simple as "configure/make/make install" writing and ebuild is very easy.
  • Contribution is easy: Contributing new ebuilds is fairly painless, from there you can get as involved as you like

Of course there are downsides, not least of all your machine spends a considerable amount of time building things and if your run a large selection of "unstable" packages you may find you occasionally need to fix-up your machine. However I find these disadvantages minor compared to giving me an up to date platform with which to contribute to upstream from.

does anyone have any resources for learning assembly language on x86? I'm trying to debug a program in MSVC++6 and frequently come across assembly (like stepping into memcpy).. Previously I just ignored these but memcpy keeps throwing exceptions and I need to find out why..

Any help would be appreciated :)

EDIT:Wow, lots of great resources.. I wish I could mark everything as accepted answer :P

HINT: combine anyone? :P

New edit: I just looked through the answers, and these seemed the best:

Aseraphim's post specific to intel x86

jkchong's post for a more introductory text

Dunteman's "Assembly Language Step by Step" is a pretty good starting point for x86 assembly.

I'm sure there are good tutorial sites on the Net, but I'm not familiar with them.

We used Microcomputer Experimentation with the IBM PC and Assembly Language Step-By-Step when I took it in school (back in the 1900s). Both are pretty good introductory books.

I've been wanting to learn assembly for a while now, and although I've tried a few times before, I haven't really been able to get past "Hello, world". Are there any good introductory tutorials to assembly (preferably using NASM, as I use Windows and Linux)?
I do have a bit of C knowledge, but mainly code in higher-level languages such as Ruby, Python, C# and JavaScript.

For my Assembly language class, we're using the book that Bill recommends. My professor also recommended this book: Assembly Language Step-by-step: Programming with DOS and Linux. He said that this is the only book that he knows of that covers NASM (and it's a tad outdated).

As a preface, I really do not want the exact solution to my problem, just guidance. I don't want you to give me the code. This isn't homework, it's just an exercise I'm trying to solve.

I just want you to tell me how to access VDU and directly change character on same screen.

The screen is divided into 25 rows and 80 columns. The characters that are displayed on the screen are stored in a special memory called VDU memory (not to be confused with ordinary memory). Each character displayed on the screen occupies two bytes in VDU memory.

The first of these bytes contains the ASCII value of the character being displayed, whereas, the second byte contains the colour in which the character is displayed. For example, the ASCII value of the character present on zeroth row and zeroth column on the screen is stored at location number 0xB8000000.

Therefore the colour of this character would be present at location number 0xB8000000 + 1. Similarly ASCII value of character in row 0, col 1 will be at location 0xB8000000 + 2, and its colour at 0xB8000000 + 3.

My task:

With this knowledge write a program which when executed would keep converting every capital letter on the screen to small case letter and every small case letter to capital letter. The procedure should stop the moment the user hits a key from the keyboard. This is an activity of a rampant Virus called Dancing Dolls. (For monochrome adapter, use 0xB0000000 instead of 0xB8000000).

Really I don't have any idea to build this code. I'm stuck at even getting started.

You are referring to what was once called the video refresh buffer. It's important to state that Dancing Dolls was a virus for DOS.

Basically, you are expecting video memory to be at address 0xB8000000 on your program's memory. However, modern Operating Systems (like Linux/Windows/Mac OS X) provide a virtual memory mechanism that prevents applications from manipulating devices directly. So the 0xB8000000 address your application sees is not the physical address 0xb8000000 that corresponds to the video refresh buffer. The last post of this thread also has some interesting info on this subject.

Nevertheless, the technique you are interested in is still valid for 16-bit DOS and is covered on the book Assembly Language Step-by-step: Programming with DOS and Linux. This book has a great section on chapter 6 that explains how this work exactly. The section is named Inspecting the Video Refresh Buffer with DEBUG, and has an interesting example that shows how to use debug.exe to access the video memory and modify it. I tested it successfully on cmd.exe of my Win 7 box.

But if you want to manipulate the screen of a Linux terminal, check ncurses:

It is a library of functions that manage an application's display on character-cell terminals

I have been able to find plenty of 16 and 32-bit NASM assembly references like here, but the only thing I could find on 64-bit NASM was what was in the small section of the NASM manual here. Are there any good sites or books that would have a better explanation of 64-bit assembly (Windows or Linux/Unix) with some good code examples?