3 ms·
If you want to learn x86 assembly, I recommend one of my favorite books Programming From The Ground Up: http://savannah.nongnu.org/projects/pgubook/ http://sav
by pkrumins 10y ago
If you want to learn x86 assembly, I recommend one of my favorite books Programming From The Ground Up:
http://savannah.nongnu.org/projects/pgubook/ http://savannah.nongnu.org/projects/pgubook/ (free pdf!)
This is a practical book and teaches assembly programming on Linux.
Author Jonathan Bartlett wrote this book because he was frustrated to no end with the existing books. At the end of them he could still ask, "How does the computer really work?" and not have a good answer. Jonathan's goal is to take you from knowing nothing about programming to understanding how to think, write, and learn like a programmer. You won't know everything, but you will have a background for how everything fits together.
Fun story: I remember how I went through this book in 2004, a day before a job interview, and I exactly got asked a question about how C functions get compiled to assembly, how the stack and memory management works. I got that job.
- bogomipz 10y agoHa, that page is frozen in 2004, its like a web time capsule! The book is really good though. Not sure I would have found this otherwise, thanks for sharing.
- userbinator 10y agoFor "How does the computer really work?" questions, I recommend this book: http://www.charlespetzold.com/code/ http://www.charlespetzold.com/code/
- genop 10y agoFunny you mention that one. I have been re-reading that book the past few weeks. This book takes a bit of a different angle on explaining computers. I really enjoy the history. My only complaint would be that I think he has a Microsoft bias (but then I guess I am biased myself). And similarly, I have a minor annoyance with the OP's mention of Linux, and only Linux, when he touches on calling conventions. This bias toward one system, and ignorance of others, is typical of many websites and documentation. To be fair, the OP mostly avoids it. To be clear, great explanations of computers to me are ones that either: 1) take great care to stay completely neutral and only discuss universally shared traits across systems, 2) go to great lengths to try to be as comprehensive as possible, including many systems and all their commonalities and idiosyncracies, or 3) focus only on one system and go into great detail how it works. The more the author strays from 1, 2 or 3, the less likely I am to read their work. Petzold pays ample attention to Morse code and similar succinct ways of communicating information. In my opinion this type of focus is the mark of a skilled coder. When I look at the entries to IOCC, it is no surprise to me that Morse code is (or at least was) a frequent focus of the entrants.
- shermanyo 10y agoThis book was what made C click for me (in the few chapters I digested way back when). I actually stopped reading twice because I suddenly understood something that had blocked my progress in C, and went on my way for a year or two until I decided to pick the book up again. For a quick idea of what ASM can look like if you build up the foundations step-by-step, and understand what you're working with: .include "record-def.s" .include "linux.s" #PURPOSE: This function reads a record from the file descriptor # #INPUT: The file descriptor and a buffer # #OUTPUT: This function writes the data to the buffer # and returns a status code. # #STACK LOCAL VARIABLES .equ ST_READ_BUFFER, 8 .equ ST_FILEDES, 12 .section .text .globl read_record .type read_record, @function read_record: pushl %ebp movl %esp, %ebp pushl %ebx movl ST_FILEDES(%ebp), %ebx movl ST_READ_BUFFER(%ebp), %ecx movl $RECORD_SIZE, %edx movl $SYS_READ, %eax int $LINUX_SYSCALL #NOTE - %eax has the return value, which we will give back to our calling program popl %ebx movl %ebp, %esp popl %ebp ret With the definitions in place, its like a whole different language. For reference, the definitions are simply a text file with contents similar to: #System Call Numbers .equ SYS_EXIT, 1 .equ SYS_READ, 3 .equ SYS_WRITE, 4 .equ SYS_OPEN, 5 .equ SYS_CLOSE, 6 .equ SYS_BRK, 45 Or (record-defs.s in the example) clearly describing the data with: .equ RECORD_FIRSTNAME, 0 .equ RECORD_LASTNAME, 40 .equ RECORD_ADDRESS, 80 .equ RECORD_AGE, 320 .equ RECORD_SIZE, 324 This book opened my eyes to the concrete, data driven nature of the problems I'm trying to solve, at an atomic level. It somehow dispelled all the magic behind programming, while exciting the mechanical side of my brain, leaving me with that "its just a machine, I can solve any problem if I just trace things patiently until I understand the parts and how they interact".
- d0mine 10y agoUnrelated: the code is equivalent to read(fd, buf, RECORD_SIZE) that may read less than RECORD_SIZE. The function should read in a loop, to fulfill its contract (read a record). #include <unistd.h> ssize_t read_record(int fd, void* buf, size_t record_size, size_t* written) { for (*written = 0; *written < record_size; ) { ssize_t n = read(fd, (char*)buf + *written, record_size - *written); if (n < 1) return n; /* error or EOF */ *written += n; } return *written; }