How would a curious programmer go about learning AssemblyLanguage
? Any particularly good/bad books?
To get a taste of it, I've referenced MichaelAbrash's GraphicsProgrammingBlackBook, and DebuggingApplications by JohnRobbins. The latter is a book on debugging (Chapter 1, using assert, Chapter 2, writing your own debugger....). Neither would I consider adequate for programming in AssemblyLanguage, but I think they make a decent high-level overview.
- AssemblyLanguage isn't "just another language". To learn an assembly language is to learn the architecture of the CPU in question -- at least, the parts of it made visible to machine instructions. If you don't know anything about how CPUs work, you need to learn something about that first -- or at the same time as learning the assembly for the CPU. One cannot learn just the one without learning a fair amount of the other.
- Specifically, one needs to have some notion about registers (which on some machines come in several flavors, e.g. bit-vector/integer, floating point, machine address), how ALUs work, and for any serious work, why circuits are clocked and why some instructions may take more than one clock, how first and second level caches work, etc -- and more, like how MMUs and DMA work, for OS or embedded work. One needn't know electronic design per se, but this is right at the border between software and hardware, so it helps to know the basics of digital design. Conversely, many have begun to learn things about digital design by starting with assembly language. -- DougMerritt
. It's free, very good and give a lot of informations about the C/C++ compilers: a must !
by Jeff Duntemann is an excellent introductory book, for x86 assembly programming and for programming in general. Its major flaw is that it ends just as it is getting to the real meat of assembly programming.
If you don't care whether it is x86 assembly, you can obtain an early 80's microcomputer such as the AppleTwo
(or emulator) that had a built in ROM monitor with simple assember/disassember. This lets you do interactive AssemblyLanguage
programming which would speed the learning process. The inevitable reboots would also be faster. The ROMs would also be visible; a great source of high quality assembly examples.
Question: are there any interactive monitors available for the PC architecture?
Answer: try the good old 'debug', standard component of DOS since the early days and still available on my XP machine. Here's a little experiment:
- open a cmd prompt (cmd.exe)
- type the '?' command and see what's available
- type 'a 0' (assemble at address 0)
- type in your assembly code, no labels, hit enter to exit assemble mode
- type 't =0' (trace at address 0)
- type 't' repeatedly and see what the x86 registers contain
Another option to consider:
By the way, if you want an assembler that just assembles AssemblyLanguage
code, without requiring any sort of Shakespearean preamble to the meat of the metaphor, you might want to look at EricIsaacson
's A86/D86 package (both an assembler and debugger).
Eric is an engineer who worked on the original Intel assembler for the x86 product line, and few people have his grasp of what the CPU is actually up to as it juggles the bits on its way to executing an instruction.
I used to use A86 to teach my assembler class. We only had a semester, and I didn't want to waste it teaching all the arcane directives (like ASSUME NOTHING) needed to fire up the MS or IBM assemblers.
That will be $0.02 please.
Does learning assembly language with one of the "high level assemblers"
teach a student everything he needs to know about modern assembly language programming
(minus now-irrelevant historical cruft),
or is there some reason to use traditional-style A86 or NASM or the GNU assembler ?
For instruction, there is every reason (when possible) to use only traditional low-level assemblers, although high level assemblers are highly desirable for real world use.
The only reason to teach assembly language to students at all in this day and age, is as a part of the overall process of teaching them how CPUs actually get things done. If they don't need to understand the workings of CPUs, then they don't need to study any sort of assembly language at all. But if they do need to understand CPUs, then high level constructs will only obscure their understanding of what is happening at the low level.
For pedagogical purposes, at the low level, it is valuable to understand the cost of general purpose versus dedicated-purpose registers, the difficulty of allocating registers for data calculations and address references, the number of instructions required to do 128-bit arithmetic on a 32-bit CPU, what high level control constructs (IF/WHILE/FOR/SWITCH) look like when translated to assembler, etc.
For real world use, on the other hand, sometimes one needs to escape to assembly for performance reasons or to access hardware resources/capabilities not accessible from a high level language, in which case the entire purpose is different, and it's desirable to have as many high level constructs as possible, as options.
So to answer the original narrowly phrased question, "Does learning assembly language with one of the 'high level assemblers' teach a student everything he needs to know about modern assembly language programming", clearly the answer is "absolutely not, in the general case". But in other cases, it depends. A future Java programmer may not "need" to know as much on the same topic. It's a bit ambiguous.
The top universities world-wide have had a fairly general answer to all such things for a very long time, though; they will tell you they are not trade schools, and that understanding of underlying theory is what is important to them. They therefore tend to teach such things "the hard way", for the best of reasons, given their goals. -- DougMerritt
The above is mostly wrong. High-level assemblers only remove some accidents of syntax, things designed to make assembly easier to parse on IBM mainframes in the 1950s, and allow the student to get down to learning the assembly language instead of the quirks of a given assembler. (I'm assuming the student has at least one traditional programming language under his belt at this point. C, Pascal, Perl: It doesn't matter as long as it has a syntax.) It allows the student to learn assembly at a controlled rate, as an extension of existing knowledge, instead of as this arbitrary intrusion that doesn't look like anything else in his programming universe.
- Pre-made control structures allow the student to focus on specific opcodes and memory access without drowning in spaghetti. (It is interesting to note that MASM has macros that do indeed define control structures.)
- A library allows the student to focus on learning how to express the algorithm of interest in assembly instead of writing the millionth broken puts implementation.
- Function call semantic sugar allows the student to focus on core logic without getting bogged down in arbitrary function call ABIs and assorted minutiae.
- An expression parser allows the student to focus on memory management (a difficult enough topic all on its own) without getting bitten by broken-by-design ALU misfeatures. (The x86 div opcode springs to mind.)
In summary: Learning assembly is about learning about low-level machine details and how to implement algorithms when customary features are missing, a task greatly simplified when the student doesn't also have to learn about low-level tool details and low-level OS details at the same time. What's more, high-level assemblers are infinitely flexible: They can provide a C- or Pascal-like language in one section of the code and the most reactionary, machine-oriented assembler in another, without requiring the student to waste his time learning multiple toolsets and fiddling about with foreign function interfaces. Accidental details don't "build character", they merely waste time.
Having been a GTA teaching assembler to sophomore and junior college students on the path to CS, CE, and EE degrees... I agree with DougMerritt. Students learning assembler need to be learning how the higher level constructs work under the hood, plus the plumbing. That includes two main sets of knowledge -- the hardware, and the fundamentals of software. For the hardware, they need to learn how one instructs the delivery of signals to and from CPUs in the general sense, how those signals are delivered on the various busses, and what those signals are doing to other parts of the board. For the software, they need to be learning such things as the basics of programs, procedures and different calling conventions, the nature of register mangling, the stack, use of frame pointers, what is actually happening with exception handling, etc. -- the lower-level concepts they'd need to know in order to write a compiler.
While something of a simplified syntax for this tasking and support libraries won't hinder this education, access to truly higher level language constructs certainly could. Students tend to use the language features available to them that are closest to their current understanding.
However, something like a powerful but straightforward macro system wouldn't be bad; it'd save the students a great deal of time doing all the same stuff they did on their last programs just to get it into initial working condition. This would let them slowly develop their own higher-level language atop Assembler. (As a GTA, I fixed much of this by simply writing up and providing a template that let them focus on the task at hand.)
Agreed. Programming a board in naked assembler teaches you what comes naturally to the board and what requires complex mangling. In the case of a general-purpose board, this is pointless - but if you're teaching EEs, they need to learn to use special purpose boards, and the assembly language is the easiest way to find out what code is simple and what code is complex. For example, an old Motorola signal-processing board can do simple array operations spectacularly fast (even having special "modulo" registers that automatically apply modulo to the address registers) but will struggle with complex algorithms. Only working in ASM will really teach the student where these proficiencies lie. However, these environments will also eventually drive the students mad with the verbosity and non-expressiveness, so a good macro package is a must.
If you just want to learn how CPUs, machine, and assembly language works, I highly recommend "CARDIAC" -- CARDboard Illustrative Aid to Computation.
Sure, it's old and outdated. But you can find online simulations.