Learning C and ASM, what's the way to go?
I'd like to learn C and ASM (on x86-64) The documentation I have varies between old books from the 70's, and tutorials from websites with the grammar of 16 year olds, from miserable sites. I'm not sure how best to attack this problem. I'd like to learn how to program in C and in ASM, I've read basic things, and understand their usefulness, but I don't know what to read! I have a number of people tell me that they've read near to nothing, but I don't think I have this sort of mindset.
Kind elders of Y, give me guidance.
Thanks
43 comments
[ 3.1 ms ] story [ 101 ms ] threadThe x86 instruction set is kludges built upon kludges, and you're never going to understand it fully if you try to jump in at the end without seeing how it developed.
Thanks for your help cperciva.
486 and Pentium didn't really do much instruction set wise (sure there were changes), then the next big change is the 64 bit systems.
edit: What do you mean kludges ? It's the most orthogonal instruction set known to man!
You used to need them (badly), especially on the smaller CPUs because otherwise you were severely limited in memory.
Check out the 'mixed models' that were pretty common usage in the 80's.
There were lots of them:
I was so happy when I finally got out of 'model hell' and could use 'flat' mode using DJGPP. Finally C programming without the headaches.http://en.wikipedia.org/wiki/DJGPP
In other words, if you really really insisted you could mess around with giving the segment registers different base values and / or lengths but you'd probably end up regretting it.
I have only good things to say about MIPS as a great place to learn ASM. The thing is, the better you understand how processors and pipelines work, the better you'll understand why instruction sets are the way they are.
If you want to learn a very bad assembler (for programmers) but one that's very to understand (for microcontroller designers), there's always 68HC11. How do two 8-bit registers and two 16-bit registers make you feel? (Probably like going to/from memory quite a bit :)
80386 Programming Guide
And the intel reference manuals.
Here's a link:
http://savannah.nongnu.org/projects/pgubook/
For assembly I've had a good experience with K. Irvine's Assembly Language for Intel-Based Computers, available on Amazon here:
http://www.amazon.com/gp/product/0132304686?ie=UTF8&tag=...
I've taught a couple people basic x86 assembly using a programmable assembler we wrote in Ruby. A really great place to start with assembly is to be able to define a array of instructions and be able to "jump in" to them and see what they do.
I'll probably make a purchase when I get my paycheck though, thanks!
In addition, I've found if you're taking an engineering approach, "Applications Programming in ANSI C" by Johnsonbaugh & Kalin was to me a very valuable learning tool.
Do not go without the "C: A Reference Manual" by Harbison & Steele, which to me has been the most valuable reference book to have on my person if I couldn't get or chose not to fancy a good Internet reference.
For Assembly, my coverage has been limited to MIPS, which was in comparison to Intel's version, a lot easier to understand and thus learn from. Check out "Computer Architecture and Design" by Patterson & Hennesy. While of course mostly a book on architecture, it's rooted in learning MIPS to understand architecture and comes with the SPIM simulator software(which I assume could be had online). I also own the book by Bryant & O'Hallaron, "Computer Systems: A Programmer's Perspective" and personally I found that learning MIPS first brought home Intel's ASM a little softer.
Thanks again!
You talked about learning C and ASM, and K&R and the other books (excluding C:ARM and CS:APP) are fine learning tools. So to answer your question, do not read it first, but have it by your side when something isn't clear... think of it like a dictionary to look up functions that were not well addressed (or even talked about at all) in the learning books.
For Asm, I concur with cperciva that the best way to go is to start at 8086 and work your way towards more modern assembly.
For 8086 I highly recommend "The 80x86 IBM PC and Compatible Computers (Volumes I & II): Assembly Language, Design, and Interfacing". I learned from this book and thought it was very helpful.
For more modern stuff I really enjoyed "Computer Systems: A Programmer's Perspective". It will be most beneficial after reading through K&R and being familiar with ASM. It focuses a lot on programming techniques, tips, and tricks so that compiled C/C++ code is turned into efficient assembly.
Finally, if you'd like to build a whole system end to end, the Motorola 68HC11 microcontroller is a fun little piece of hardware to play around with. "MC68HC11: An Introduction to Software and Hardware Interfacing" is a good book for this purpose.
Best wishes on your journey into the low-level programming world!
PS. I'm biased. I have read and own all of the above mentioned books. Thanks for getting me to brush off the dust again ;)
So pic, mips, etc first, then X86
If you just want mercenary ability with C and ASM, you'll have no problem finding the resources - just a matter of finding the best book. I'm sure you'll get plenty of recommendations here.
It sounds you want to enrich your general programming knowledge though. In that case I'd recommend learning computer architecture concepts - once you have that down, learning C and ASM will be a pretty transparent process. In fact, I'd recommend it even if you just need it to hack on something specific. I took an architecture course at uni that used this book, and it was pretty decent: http://www.amazon.com/Computer-Organization-Design-Fourth-Ar...
First read "Code" by Charles Petzold. This book will get you "in the mood" and in the right frame of mind: http://www.amazon.com/Code-Language-Computer-Hardware-Softwa...
Then I suggest you pick up a good book on Assembler. This might be a good choice: http://www.amazon.com/Professional-Assembly-Language-Program...
Start writing some drivers for Linux. Like a memdrive or something. Do it all in Assembler! Oh, you need to read other books on how to do this...
Then pick up the K&R book on C. Now write your memdrive driver in C.
That should get you started. I think it will take you at least up to two years before you're passed the learning curve and to be comfortable with this level of programming.
Oh, you need to be willing to do it for the love of it because it's highly unlikely that you will make a living using these sort of technologies (nowadays).
Good luck!
PS: I miss the old days...
Low level assembly is what you want, that presumably includes interfacing with you favorite C code.
Calling conventions, stack frames and so on.
Besides, the boilerplate runtime stuff has nothing to do with writing kernel code, so a 'trivial hello world' program will have a lot of cruft added to it:
that's not that bad.Note the stack frame alignment trick, the fact that 'printf' was specified in the source but puts is being called!
I think I must have coded myself to the moon and back by now if you'd print it all out on fanfold paper (in C, mostly), but the joy of getting a little OS to boot up from nothing is never going to pale in comparison to installing framework X and building some web-app. No matter how successful.
Web-apps make substantially more $ though...
Some people will learn just for the fun of learning.
Like other commentors, K&R would be my best recommendation for the second book. You might as well start off on the right path towards enlightenment.
Thanks!
The reasons I chose it are
(1) It's introductory, i.e., a good first book for a complete noob. (2) It's very Linux-centric. Most good books on assembly language assume you use Windows or even DOS it seems. (3) One of the reviews says, "you will get a good workout using the gdb debugger." Sounds like fun.