Programming from the Ground Up [pdf]
download-mirror.savannah.gnu.org
download-mirror.savannah.gnu.org
(1) Start off by making changes to a program that someone/some book gave us as a basis and blindly stumble through some changes and compiler/interpreter/runtime errors.
(2) Take a step back, absorb what we've learned from the errors.
(3) Read more about the principles of the programming language/OS/API/operating environment.
(4) Internalize concepts behind the language/OS/API/operating environment.
(5) Goto (1).
It's only after many iterations through this process that I can now see similarities among different processors (CPU/DSP/GPU/etc), operating systems, APIs, programming languages. So many classes of problems can be solved effectively without ever understanding these details, so it makes sense for those new programmers not to learn the details at first. IMO, this is at least an intermediate-level text.
Would anyone actually recommend to a beginner to start learn assembly first?
Yes, if you can find a good book about it. Assembler isn't particularly difficult, but the information teaching it is rather hard.
Right now, the lowest-level language I know of with a really good beginner book is C, and it's this book: http://smile.amazon.com/Absolute-Beginners-Guide-C-2nd/dp/06...
Now that I think of it, I should give my mum a call :)
I hope my books do too :)
http://www.amazon.com/Programming-Absolute-Beginners-Guide-3...
The front cover says it's been "Updated for C11", but all the sample programs use "main()" rather than "int main(void)". The form without an explicit return type has been invalid since C99.
Page 11:
"In 1983, ANSI created the X3J11 committee to set a standard version of C. This became known as ANSI C. The most recent version of ANSI C, C11, was formally adopted in 2011."
That's loosely correct, but in fact the 1990, 1999, and 2011 editions of the C standard were published by ISO, not by ANSI (and later adopted by ANSI). Furthermore, it ignores the fact that the phrase "ANSI C" is commonly but incorrectly used to refer to the 1989/1990 version of the language (see gcc's "-ansi" option, for example).
Page 16:
"These are functions:
main() calcIt() printf() strlen()
and these are commands:
return while int if float"
No, those aren't "commands", they're keywords. I can't think of any reasonable meaning of the word "command" that would include "int".
Page 26:
The sample program listing is not properly indented.
Page 36:
"\b moves the cursor back a line".
No, it moves the cursor back a column.
A book for beginning C programmers should not have these kinds of errors after three editions.
as for simulators i enjoyed using MARS: http://courses.missouristate.edu/KenVollmar/MARS/
Also of note is the author's story of writing the book and giving it away as a labor of love. Very nice
In CS you're usually started off with something like C, Java, or Python. But those languages are so HUGE (in comparison) that it can be really overwhelming. Meanwhile, with assembly, you have far fewer items in your toolbox and you have no abstractions between what you write and what's being executed.
After googling, I found emu8086 [0], which I think is what I used to debug the tiny apps I was writing. It was great! You could step back and forward in time, and you could inspect every detail.
Probably in order: 6502---not my favorite, but tons of material and emulators exist. The most popular 8 bit CPU and one of the most simple ones.
6809---my favorite 8-bit and it lends itself fairly well towards higher level languages. A nice register set (2 8bit general purpose registers, four 16bit index registers) and a regular instruction set makes it easy to program.
8080 (or Z80)---if you are going to start down the dark side of x86 line, it's probably best to start at the beginning. A mess of registers, most of which are somewhat general purpose but each has a specific use.
68000---a very nice 32-bit architecture with enough regularity to make it easy to write compilers for, with enough instructions to make it fun to write assembly code. 8 32bit data registers, 8 32bit index registers.
VAX---another nice 32-bit architecture with a very regular instruction set. 16 32bit general purpose registers.
MIPS---one of the original RISC architectures that's still in use. Perhaps a bit too spare on instructions. 32 32bit registers.
ARM---Kind of reminds me of a RISCish 68000 with unique features that make it, again, fun to program at the assembly level.
The x86 line is ... baroque due to its history (you can think of it as an overglorified 8080 that gained power over time, much like the MCP in TRON if you think about it) of ossified layers. It's hard to learn because it's almost all exceptions to a non-regular instruction format.
6502 was my first (and only really significant) experience with assembly. It is so minimal as to be awkward at times, but as you say with the huge numbers of emulators and instructional materials around, it's hard to discount it.
Personally, I would skip x86 altogether unless you actually want to do x86 programming ;-). I've never looked at ARM, but your description makes me want to play with it. The added bonus is that it is still relevant today.
Question for you, if you happen to come back to this: what's the best documentation on ARM that you've found? Every time I try to find some, it seems like I'm supposed to pay for a license, and I get confused.
You say x86 is not a good choice to learn, but this book purports to make assembly for this architecture accessible. If you stand by your opinion, are there even CPUs readily available that support the alternative architectures you mention?
Also, can anyone recommend this or any other book or learning resource?
Then I read a book that explained how assembly works and how a compiler would implement C's features with assembly. It all clicked since then. Too bad I've forgotten the name of the book.
python --> boolean algebra + logic gates --> assembly --> c + java
It used to be
scheme + boolean algebra + logic gates --> assembly + unix programming in c (threads, pipes)
but that was a bit too hardcore for freshman in first semester
Dead nameservers are relatively rare among sites that get posted to HN, since many are high traffic and use CDNs (that rely on DNS kludges). But it is still a regular occurrence. No one ever talks about it. But it's one of the DNS kludges that's continually slowing things down behind the scenes.
There is that term "link rot" for URL's that do not work anymore. And "bit rot" for source code. I propose a new one: "NS rot".
This one is quite expansive in coverage of topics.
So I know the basic idea of registers and addressing modes and pipelines and stuff, but nothing specific to any architecture. My goal is basically to be able to write faster C and C++ programs and analyze constructs like the cost of things like smart pointers, virtual dispatch, templates, etc.
See http://news.ycombinator.com/item?id=6845367
Simple, portable shell script. Not perfect, but it still works. ^M means Ctrl-V,Ctrl-M in ed/ex/vi
#!/bin/sh
# requirements:
# netcat
# openssl
# sed
# optional: strings
# optional: addcr
type strings 2>&1 >/dev/null ||
strings(){ sed ;}
type addcr 2>&1 >/dev/null ||
addcr(){ sed ;}
[ $# -gt 0 ]||exec echo usage: $0 nameofblog
{
printf "GET / HTTP/1.0\r\n";
printf "Host: $1.blogspot.com\r\n";
printf "Connection: Close\r\n";
printf "\r\n";
} \
|exec nc -vv www.blogger.com 80 \
|exec sed '
s/\\046/\&/g;
s/\\46/\&/g;
s/\\075/=/g;
s/\\75/=/g;
/targetBlogID/!d;
s/.*targetBlogID=//;
s/&.*//;
' |exec sed 1q \
|while read a
do
{
printf "%b" "GET /feeds/$a/posts/default HTTP/1.1\r\n";
printf "Host: www.blogger.com\r\n";
printf "Connection: Close\r\n";
printf "\r\n";
}
done \
|openssl s_client -ign_eof -connect \
www.blogger.com:443 -verify 9 \
|exec addcr \
|{
echo
sed '
s/</</g;
s/>/>/g;
s/&/\&/g;
s/"/\"/g;
1i\
<br><br>
s/<name>/<br><br>name &/g;
s/<uri>/<br>uri &/g;
s/<generator>/<br>generator &/g;
s/Blogger//;
s/<id>/<br>id &/g;
s/<published>/<br>published &/g;
s/<email>/<br>email &/g;
s/<title type=.text.>/<br><br>&/g;
s/<openSearch:totalResults>/<br>total results &/g;
s/<openSearch:startIndex>/<br>start index &/g;
s/<openSearch:itemsPerPage>/<br>items per page &/g;
s/<updated>/<br>updated &/g;
s/<thr:total>/<br>thr:total &/g;
s/<\/feed>/&<br><br><br>/;
s/^M*/<br>/;
' \
|strings
}Controversial news articles, whose entire content can be summed up in the headline, collect both upvotes and comments. The ranking algorithm punishes submissions with many comments, to push those submissions off the front page.
~(Score) = votes / time
Also, people open links, upvote if they like it, and then continue reading (most of the time). That way if their reading is interrupted, they can check their "saved stories" to get back to reading later.