Why Learning Assembly Language Is Still Good
nickirelan writes "Why Learning Assembly Language Is Still a Good Idea by Randall Hyde -- Randall Hyde makes his case for why learning assembly language is still relevant today. The key, says Randall, is to learn how to efficiently implement an application, and the best implementations are written by those who've mastered assembly language. Randall is the author of Write Great Code (from No Starch Press)."
Assembly is great because you can kill any linux system you got ssh access to using assembly.
9/11: Never forget it was a false-flag operation
Another reason: Sooner or later, you'll need to debug something without a source-level debugger. Knowing how to debug raw assembly language has saved my ass many times.
any one there ?
Also, don't forget, a good deal of programming is still done in assembly. Both in a job I've had coding stuff and in my current research (crypto), I did/do a lot of assembly programming. Yes, learning assembly will make a better programmer out of those who never will code assembly again, but for some people, assembly is a valuable and often-used skill
It's a shame that schools are phasing assembly classes out of their computer science curriculums. If anything, it makes for a great foundation on which to learn more modern languages while teaching students things about computers that they probably wouldn't take the time to learn otherwise.
Hate to say, but the kind of optimization you learn about by knowing assembly language is just not necessary for most programmers these days.
I learned programming in the 80's, and I did learn assembly language, starting with 6502 assembly. I would subconciously code my C so that it would produce faster code. Every block of code I wrote would be optimized as much as practical. My code was fast and confusing.
When coding Perl or Java I would keep in mind the details of the underlying virtual machine so I could avoid wasteful string concatenation or whatever. I cache things whenever possible, use temp variables all the time, etc., etc.
I've spent the last few years trying to UNLEARN this useless habit. There is just no need. And in highly dynamic languages like Ruby, it's pointless. You can't predict where the bottlenecks will show up.. almost every project I've worked on has either had no performance problems, or had a couple major performance problems that were solved by profiling and correcting a bad algorithm.
Stuff like XP and agile development have it right: code as simply as possible, don't code for performance, then when you need performance you can drill down and figure out how to do it.
To me a beautiful piece of code is one that is so simple it does exactly what it needs, and nothing more, and it reads like pseudo-code. Minimalism is the name of the game.
So my advice is, don't learn assembly language. Learn Lisp or another abstract language. Think in terms of functions and algorithms, not registers and page faults. Learn to program minimally.
On another note, the tab in my Konqueror for this article reads: "Slashdot | Why Learning Ass...". Heh. :-)
Come on - all that may be great, but what really matters is what gives the most bang(features) for the buck (cheapest)... and in the minds of the average CEO with 10 billion options this is done by outsourcing to the lowest cost provider (India, China, etc..) regardless of code training, language etc..
Unfortunatly, I doubt that we are going to see many people switching to assembly language, but we can hope. I'd love to see a return to applications that were under 100K
Misuse of high level languages such as visual basic, as well as off the shelf components for everything, has led to a level of code bloat in todays applications that is inexcusable.
(note: off the shelf components and high level languages aren't inherently bad, just not always suitable for commercial applications.)
Also, given that modern optimizing C compilers can often optimize better than humans, it may make sense to embed critical sections of assembly into C code, and let the compiler optimize the rest...
Also, whatever happened to profiling? Has this become a lost art among developers? Time your code. See where it bogs down. Find the fat. Cut it out. Please.
--
This post brought to you by Save the CPU Cycles!
While I learned assembly, and found it useful for learning to understand exactly how the machines think, I'm not sure I agree with his basic premise. Namely, that great code (code that is well designed for it's job, and easy to work with and under) is always the efficient code, in machine terms.
The machine thinks one way. A human thinks in another. Code that is well designed for easy updating, and extending, is code that is easy for a human to understand. If that is not the most efficient way for the machine to do it, that may be the price for 'great' code in this project. (The ideal balance depends on the project, of course. A kernel should be machine-efficient, for example.)
'Sensible' is a curse word.
"Why Learning Assembly Language Is Still Good and Why I Still Can't Get Laid"
:)
What ever happened to Intel's X86 Reference Manuals?
Efficiency in terms of coding is a wonderful art and I think it's still applicable today. Kernel-level routines, games, drivers, etc. all benefit from tight coding in assembly language.
But let's be honest here. Computer Science 101: an efficient algorithm coded in an inefficient way will always beat out an inefficient algorithm coded by hand in 100% optimized assembly. I'll put my crudely coded Javascript quicksort algorithm against your finely honed 100% assembly bubblesort algorithm any day. Not only will my algorithm beat the pants off of your algorithm, but I'll also code it in far less time and with way fewer debugging sessions than you would. Also, the higher-level language you go, the better it is for security. How easy is it to introduce things like buffer overflows, array out of bounds, etc. errors in assembly? How easy is it to do that in Java, C#, etc.?
So yes, writing in assembly language is still good and has its places. But let's keep it to those places, shall we?
Want to improve your Karma? Instead of "Post Anonymously", try the "Post Humously" option.
Learning it is good, even if one never ends up actually seriously developing in it. It advances your ability to solve problems in a language independant fashion and equips you to be able to more rapidly model solutions to brand new problems, even in the languages that you may already know.
File under 'M' for 'Manic ranting'
Knowing what assembly is and how it works is beneficial. Mastery of assembly is completely pointless for anyone outside of OS kernel, compiler construcution and embedded development...which probably means you. Your time will be better spent figuring out how to make Java programs 10% faster most of the time.
I've programmed a few embedded systems in assembly and it's not very fun at all.
To make matters worse, each CPU has it's own instruction set, and special set of commands that you must learn before you can even sit down and start writing code.
With C++ or at least a C compiler, you don't need to worry about so many implementation details. You should only resort to assembly if you absolutely, must have the performance required. Maybe the author of this article forgets how difficult it is to debug assembly code, or how difficult it is to implement abstract concepts such as OO at such a low level.
I don't agree at all that writing "efficient code" necessarily creates better code. Writing "clearer" is better from a quality standard.
We have compilers for a reason, to produce assembly code as efficiently as possible for a higher level language. Most 99% of the time, the compiler will optomize the code just as well, or better than you can.
I would still recommend learning assembly language to C++ programmers simply so they understand how the computer is actually working. But to require anyone to program in assembly requires a great deal of justification.
can you get away with naming a source file org.asm?
* rim shot
I apologize.
I think there is more at stake here than just writing efficient applications. For one thing, writing proper multi-threaded code often requires thinking at the assembly level. Many of my coworkers who are all high-level-language-only programmer types couldn't understand (until I explained it) how the Double-Checked-Locking Java example was broken.
Wow. You can crash a machine with assembly language.
That may seem impressive to you (especially if you're fourteen), but the fact is that exploits can be done in almost any language.
In other news, this doesn't have a hell of a lot to do with the posted article, either.
He's just trying to promote his invented High Level Assembly language, which is no way proper assembly. Well, read his book and judge for yourself.
Master Assembly, and you've mastered computer organization, computer architecture, compiler construction basics, logic, code optimization, and ofcourse programming (I may have missed a few).
It's no coincidence that every good programmer/compiler engineer I've met (I'm one too) has had a strong grasp of Assembly.
An Indian-American Hindu committed to non-violent thought/speech/action alarmed by the global explosion of radical Islam
from someone else's experience.
Sourcer
You need it to work on the zsnes project.
Honestly, a fair understanding of assembly language may help you in the long run, despite the fact that you can probably go your entire career without using it directly, and that you're probably going too far most times you do use it. It's just part of knowing how a computer works.
Assembly language will always be needed to optimize certain types of algorithms, that don't translate efficiently into C. Try writing a FFT algorithm on C using a DSP, and compare it to what can be done in native assembly. The difference can be an order of magnitude or more. Some processors have special purpose modulo registers and addressing modes (such as bit reverse) that don't translate well into C, at least not without extending the language. Fixed point arithmatic operations are not supported in ANSI C either, but are a common feature on special purpose processors.
For low power/embedded applications, efficiency makes sense as well. Every CPU cycle wasted chips away at battery power. A more efficient algorithm means a smaller ROM size, and the CPU can either be clocked slower (can use cheaper memory and/or CPU) or put into a halted state when it isn't needed. (longer battery life) Coding small ISRs in assembly makes sense as well, as C compilers often must make worst case assumptions about saving processor context.
That being said, only a fool would try and re-write printf or cout in assembly, if they have a C/C++ compiler handy. Hand optimization is best used as a silver bullet, for the most computationally intensive or critical functions.
My rights don't need management.
Even when you write in C it helps a lot, especially in the embedded systems field, to know what sort of code the compiler is generating. For example, say I have a i++; operation that I expect to use to set a semaphore - is that one operation, such as a Z-80's inc , or is that a lda, inca, sta operation that might be interrupted? This can matter a lot! And I have seen compilers which were inconsistent as to what sort of code they would generate for such an operation. This is just one example, but there are many more, and they can make a BIG difference.
Also, if you cannot read assembler, how are you ever going to figure out what strange compiled code, which has been stripped of its debugging symbols, is doing?
Dog is my co-pilot.
Second, and perhaps more important, I think most of the performance issues in such environments stem from architectural, not algorithmical issues. Think J2EE, where if you are not careful enough you end up doing a round trip to the server every time you set a property in an object.
In a sense, he covers this in the article when he writes:
"This doesn't mean, of course, that a practicing engineer should sacrifice project schedules, readable and maintainable code, or other important software attributes for the sake of efficiency.
What it does mean is that the software engineer should keep efficiency in mind while designing and implementing the software."
But of course, most of his emphasis is on knowing how does the machine work. I ascribe more to modern thoughts considering efficiency (and other non-functional requirements, such as the maintenability also mentioned in the above quote) as architectural concerns, things that shape the architecture and that no amount of algorithm substitution and the like can fix if gotten wrong in the first place.
The revolution will not be televised.
You know, when you're trying to get a game out the door that runs at 30fps and your competitor has a similar game running at 60fps because they coded their inner loops in assembly you begin to realize why optimization is important after all.
Doesn't it make you feel good to know that our freedoms are protected by politicans, lawyers and journalists.
I use assembly every day to program embedded controllers. There are compilers for them, but I often use controllers with a few hundred instruction words of storage space and a few dozen bytes of ram. Compilers just aren't efficient enough.
Jason
ProfQuotes
What platforms would you use to teach assembly?
Intel could give many kickbacks to university programs, but they appear to get criticized for chips with too much baggage and backward compatability.
The RISC PowerPC processor has potential, but the number of consumer desktops with it has been on the decline (Is anyone but Apple left?). Computers might be too expensive for some students.
A Palm Pilot / Handheld sounds like a great choice to me. They're cheap and can be synced with whatever consumer desktop the user has (I can't imagine coding assembly in Graffiti). The limited hardware is probably a plus for academic purposes.
I think this fellow makes some great points, but what platform and tools would you choose to learn assembly with?
Well Bootloaders and ISR forced me to learn assembly. If you're going to do system programming then I'd highly recommend learning it. Otherwise I don't think its really nessacery.
While the majority of the Unreal engine is C++, we often write assembly-code versions of critical functions for specific platforms. Of course this is done after the C++ versions are tried and tested, and the bottlenecks are idetified.
To take full advantage of processor features like SSE or AltiVec you don't really have a choice.
For example, UT2004 contains SSE and AltiVec assembly versions of some of the vector and matrix manipulation functions, some of the visibility culling code, etc. The amount of work Dan Vogel put into this kind of optimization is one of the reasons that UT2004 runs better than UT2003 on the same hardware.
Learning assembly language is useful, as it's sometimes the right tool for the job.
The "Art of Assembly Language", anyone?
mov ax, assembly
learning ax
mov bx, good
is ax, bx
I have very fond memories of writing pentium-optimised asm...the rules were complicated enough to make things interesting, but still comprehensible.
Nowadays, the x86 ISA is just an API...god knows how the core actually executes instructions and in what order, which makes it very hard to optimise code beyond a certain point. You get more mileage from optimising memory access patterns and doing other such dull, dull, dull work. I get my asm coding fix elsewhere nowadays.
Checkem out.
menuetos
Unununium Operating System
Nasm is the portable type assembler. Pretty cool.
just try to code assembly without functions. :)
Got my education in mechanical eng. once upon a time but was able to take a course on uprocessor applications and then ucontrollers (8bit) for robotics. No high level language here. Just straight Assembly code to fit in 32K of memory. You'd be surprised how much you can fit in there. Programs were fast and had to be efficient and I learned alot about architecture, as much as a mech eng could of course.
Even in open source apps, getting something out there ready to play with is key. Actually this may be even more central to open source ecosystems than corporate development. Would you prefer that the Mozilla developers have taken the assembly route? They'd probably be well on their way to rendering the bold tag by now but thats about it.
Assembly is a great idea when speed and compactness is necessary, but it's tough to do it well on some processor architectures, RISC in particular. A well-tuned compiler backend for those can probably out-code most (but not all) humans - and the more registers you have to keep track of, the bigger the gap. But even CISC (or CISC-like) architectures can be problematic. Consider branch prediction, to cite one example. As much as I loved getting down to the "bare metal" on the 6800 and 68000, I'm glad I can use something else today.
I would expect such blatant racism on Fark, but on Slashdot? Mods please ban this asshole.
Here they are.
Or you may prefer AMD-64, here.
Quoting: "the best implementations are written by those who've mastered assembly language".
I haven't read this book, but I'd hope that there would be some pretty good justification of the above statement. I suspect that it's not, though. First of all, who defines what the "best implementation" is?
As Knuth says, the first rule of program optimization is: "Don't do it". Trying to optimize a program when you're writing it leads to all sorts of problems including difficult to maintain code, increated time and budget required for the project, and often it's not even a hot spot anyway.
I used to be very concerned about using making my code fast, but have (over the decades) decided that making it obvious is much more important than speed, particularly in the initial implementation. Profiling allows you to concentrate on the 20% of the code that the program is actually spending 80% of it's time in, instead of guessing where the hot spots are going to be.
I've found that another benefit of using simpler code is that I'm more likely to throw away whole sections of simpler code and try radically different algorithms or mechanisms. More complicated code I find I'll try to just tweek instead of dumping wholesale. Randically different approaches can lead to 10x speedups where tweeks of existing code may give you 2x speedups, if you're lucky.
Don't get me wrong, I'm all for trying different approaches. I'm not sure I would have come to the same conclusion I have now if I hadn't spent quite a long time trying to write optimized code. It was a very different world back then, but I know I wasted a lot of time optimizing code that didn't at all need it. It was an experience though.
Sean
Even if you never write a single line of assembly in your life there are times when you might need to understand the concepts - for example you might need to embed an interpreter for a language in your software and use a virtual machine. Before you do that it might be a good idea to know how people have designed real machines.
Doesn't it make you feel good to know that our freedoms are protected by politicans, lawyers and journalists.
At Boston University they teach us on MIPS. It was actually one of the easier courses I took there, but maybe that's because I've done a lot more programming than the average BU CS student.
I would have rather bitten the bullet and learned x86, because I could actually USE that for something.
But there is another kind of evil that we must fear most... and that is the indifference of good men.
Just like I learned on in college. Ours were 6502 boards with a bunch of other stuff on them, like D/A converters and space to wire up more stuff. At that time we used Mac Pluses as the interface to program and load the assembly into the boards.
These are produced specifically as teaching aids and I'm sure they are still available. We built all sorts of stuff on the boards including traffic light controllers, elevators control and robot servo controls. Fun stuff.
What Randy Hyde taught me is that it is important for a beginner programmer to quickly learn what kind of instructions the high level code you write is being translated into, how basic machine organization works and how the compiler and OS figure into running your code. Writting Assembly is no longer important (thank goodness) however the process of LEARNING how to write Assembly is a crucial step in a well rounded CS curriculum.
When Randy Hyde taught x86 Assembly to us at UC Riverside it was the toughest lower-division class and the weeder for the people who shouldn't be computer scientists. Without that core people are making it to upper-division and performing very poorly in OS, compilers and architecture.
...is not to fear Binary Arithmetic. It's just like regular arithmetic -- if you're missing 9 fingers.
"My country, right or wrong; if right, to be kept right; and if wrong, to be set right." --Senator Carl Schurz (1872)
That somebody has to write an article to state this obvious point shows the sad state of programming that the 90's guerilla engineering training has brought us.
(You too can earn a 6 digit salary in computer programming after our simple 2 week course that guarantees certification!)
It's a tradeoff between maximally efficient code and simple code. Complicating matters further, in many cases what you'd think would be "maximally efficient" code isn't actually maximally efficient anymore, given that it's hard to predict what exactly is going to happen when your code is run through an optimizing compiler and then run on a pipelined CPU. In some cases silly optimization tricks C programmers who know assembly do actually slow down the code, because if they had written something simpler, the compiler could have optimized it, and the compiler knows better optimizations (or can compute better optimizations by looking at literally millions of different factors).
Optimization tricks are also notoriously brittle--they're clever hacks that solve a particular problem more efficiently than the straightforward solution. The problem is that if you want to change things, the trick may not work anymore, so you're stuck rewriting it, or often you end up with subtle bugs, because you relied on some clever hacks whose assumptions no longer hold.
And finally, "optimization" of the assembly-programmer sort often has negligible effects. If you actually profile, the biggest speed hits are invariably in a very few places. Most of your other "optimizations" are going to be making 0.001% speedups, if they even speed anything up at all (and sometimes they slow things down!). That's not only not worth it, it's detrimental to your application's development.
This is even more of a problem in higher-level languages. Lisp, Haskell, and other functional languages do all sorts of stuff under the hood to optimize things, and various scattered parts of your code can interact (if some redundancies are found that can be optimized away, even across modules) so premature optimization is generally a bad idea.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
In past years, I noticed people who learned assembly previously are usually good C/C++ coders. I believe this is because knowing what machine really does at it's instruction level helps to imagine how it should be written in higher language. It is sad that Java and C# exists just because former visual basic people can't grasp a concept of a C pointer.
What makes assembly superior is a hardware where resources such as memory or cpu speed are very scarce: embedded devices. Microcontrollers. Either you need less energy, either you stuff there more functionality, in critical systems that counts.
Myself I began my coding experience on Z80, typing instructions on hexpad. Using own mind as an assembler, to this very day I remember 00 is a nop, C3 is jmp and C9 is a ret. Being able to do hex subtraction in head brought me great popularity in my first job, where reading cobol dumps from Univac mainframe was common daily task for programmers, usually trained in "higher" language only.
Even today, unlike bugs in other software, compiler defects could be found only with a good understanding of assembly language.
There you are, staring at me again.
Assembly will educate your logic and your ability to think like the very machine does. Compilers, in the long run, just fade out that close feeling for effective code and noone - ever - can convince me that a compiler can optimize code better than a good assembly programmer. Being an assembly junkie myself, having won all benchmarks ever, still dreaming about the CPU cycles saved when using a moveq instead of move.l, I think assembly never will die out. SMON, where are you. And O.M.A., I hope you rest in peace.
-- The Online Photo Editor - http://www.phixr.com
It's still the best way to produce a program that runs fast and with minimal resources. I wrote my first assembly language program in 1964, probably before a lot of you folks were born. The bulk of my assembly language programming has been for various microprocessors going back to the Fairchild/Mostek F-8, a horrible chip set, but it worked and was relatively cheap at the time (1976). I've done a lot on 8085 and 8051 systems for agricultural control systems and elevator (vertical transportation) controllers which are still supported some 20 years after they were first designed.
If you understand assembly language, then you understand the intimate details of the system you are programming for.
"Do the Right Thing. It will gratify some people and astound the rest." - Mark Twain
"Do the Right Thing. It will gratify some people and astound the rest." - Mark Twain
Computing is all about layers. To be really good at the layer you work at, you need to know something about the layers above you and the layers below you. For C/C++ programming, this means having an understanding of assembly and how the operating system works. I've seen many bad implementations when progammers did not understand the consquences of what they were doing.
If you want to teach somebody 6502 assembly language, then find somebody on the forums at NESdev who's struggling.
OK, is there (should there be?) anything like this for PowerPC assembly? I'm aware of these web pages:
I see very few links between the way I code in assembly, and how I write the higher-level languages. Yet according to this article I should have the makings of a guru. Where am I going wrong?
Presumably everyone understands binary encoding, shift right and left instructions, and the like? Anything much beyond this is liable to be very architecture-specific - which is bad. I look forward to the day when I can choose between a number of architectures and run the same open-source programs on each. I loathe X86, and I dislike apple for other reasons.
Perhaps we become more rigourous by writing assembly for small systems - with very few resources. But beyond this, I can see no real advantages to learning assembly.
I regard myself as a good programmer, but I see my strengths as being clarity of expression and design.
Skywolf
Probably the best reason to learn ASM is so you can code your own viruses instead of stealing my own GPL'd malware.
I think learning compilers and how they will take your code and mangle it into machine code is more important than learning assembly, specifically. Building your own compiler will require you to learn some assembly (or at least the notion of it) which is sufficient for this purpose.
In the real world, you generally don't write an application targetted to a specific CPU. You trust that your compiler is generally going to produce efficient machine code for your algorithm. Sometimes it won't, but if there isn't a performance problem with that particular section of code it usually isn't worth the effort to do anything about it.
The point of using a profiler to optimize your application is that usually you're going to identify a couple key areas where you need to do some tuning because your algorithm is not efficient regardless of the architecture on which its running.
Further, within the x86 family, different CPUs have different performance characteristics. The most efficient machine code on one may be the slowest on another. So to write the most efficient programs for x86, according to this guy's definition, I would end up having to implement run time CPU checking with different code paths depending on the result.
Guess what? It isn't worth the additional development time unless the result is substantial. How do we know which improvements would be substanial? We profile the code.
This guy needs to take a leave of absence from teaching and work as a programmer for a while before he shoots off his mouth on topics where he clearly has no clue.
Or rather, Art of Assembly. Possibly the best information on assembly language programming I've ever seen!
XML is like violence. If it doesn't solve the problem, use more.
Given that one of the keywords in most assembly languages is ORG, stating the origin point where the assembly begins, yes you can if you're compiling it with an assembler called Orgasm or another assembler called Orgasm.
I'm fully in favor that most programmers should learn some assembly. But learning how to do efficient code is not the reason for learning assembly. Assembly should be learned thoroughly by systems programmers (who write operating systems, core libraries, compilers, etc) and certain embedded programmers because they might actually need to use that skill directly. Other programmers should learn some to the extent that it teaches them what's really going on inside the machine, but they should not dwell on it (unless they find it fun). Efficiency should focus on choosing (or developing) the proper algorithms for the application being developed.
If one is going to do programming where pointers would be used (systems programming and lower level applications programming, such as in C), then I suggest learning assembly as the first language. Two or more decades ago, that advice worked because most people didn't learn to program until they took a class in it or such. Now days, people destined to be programmers are learning some programming by around age 10 (usually in whatever language is easiest to get started in, which is generally not always the best to develop larger applications in). By the time they've done a lot of programming, they either "get it" with regard to pointers, or don't, and are set that way for life. This is unfortunate (and results in much insecure programming).
now we need to go OSS in diesel cars
However, My most sought after skill with my peers was not debugging programs, but using DOS debug to hack around the copy protect schemes in use at the time for various apps and games...
From excellent karma to terible karma with a single +5 funny post...
So long as we are talking about making full applications work in assembly in the target system.
(ie: not so much about the code & algorithms, but abouut how that code exists in the system.)
Understanding the OS, how sockets are dealt with, what context switches are, how shared libraries are handled (ie: Windows and Linux are VERY different in this regard, and not understanding this can lead you to write really shitty applications) is very important.
I've had to use so many applications that just SUCK from a systems point of view, because they were written without consideration for the target system.
I think assembly still has a lot to teach us, but it's no longer simply in the area of optimized instructions... that is done almost as well, if not better overall, by compilers nowadays. The real trick is that working in assembly makes you learn how the OS *really* works, and moves data around.. and that's what you really need to know.
This guy says "Efficiency Is the Key". This guy is wrong.
With the incredible power provided to us by modern CPU's, efficiency is just about completely irrelevant for 99% of non-game applications. Think... when was the last time you thought "This word processor just doesn't respond to my keypresses fast enough." or "AIM takes way too long to open a new IM window."? The reason why these programs aren't getting "faster" (as the article complains) is because there is no way to do so. They spend 99.9% of their time waiting for user input already.
Optimizing code which doesn't need optimization is Bad with a capital 'B'. When optimizing code, there is almost always a tradeoff between efficiency and maintainability. Efficiency often requires cutting corners, killing opportunities for future expansion, or, at the very least, writing ugly code. When that added efficiency does not lead to any noticeable benefit to the user, why do it?
Now, granted, you shouldn't use an O(n) algorithm when an O(lg n) one exists to solve the same problem. However, knowing the difference between O(n) and O(lg n) has nothing to do with knowing assembly. The only benefits you can get out of knowing assembly are constant-multiplier speed increases. And, frankly, shaving off 50% of 0.1% CPU time used is not going to help much.
Really, the speed of modern CPU's is sickening. I can't count the number of times I've written a piece of code, thought "This is going to be so slow...", then watched it execute near instantaneously. Even when running programs in a prototype programming language I'm working on -- which currently runs about 40x slower than C, because it's a crappy prototype -- this happens to me regularly. The only time your code is going to be noticeably slow is if you are processing a very, very large data set or you are using slow algorithms. In the former case, sure, knowing assembly will help, but such cases are extremely rare in typical applications. In the latter case, find a better algorithm.
seriously. WTF?
All too often, high-level language programmers pick certain high-level language sequences without any knowledge of the execution costs of those statements. Learning assembly language forces the programmer to learn the costs associated with various high-level constructs. So even if the programmer never actually writes applications in assembly language, the knowledge makes the programmer aware of the problems with certain inefficient sequences so they can avoid them in their high-level code.
Fair enough. Like he says, it works with any speed processor to make things faster.
Most of the rest sounds like praise of free software. Free software does not suffer, "unrealistic software development schedules." Free software authors can go read the source code to gcc and gcc and the gnu debugger both have had more attention lavished to them than any proprietary equivalent.
Friends don't help friends install M$ junk.
I agree totally that hand-optimized assembly is no longer necessary.
What IS often necessary is that working in assembly on a given system teaches you a lot about how the system (including the OS, library loaders, etc) actually works.
Understanding things like context switches, why some sycalls are slower than others, interrupts, and all that jazz are things that you pretty much can't pick up from high level coding.. you have to get down and dirty.
To learn better programming, for sure, learn lisp, learn to code beautiful, functional, streamlined code....
but that's all for nothing if the application uses resources in such a way that the system in question bogs down.
I myself have learned two and a half different languages at Ohio State and am trying to find time this summer around work to learn a third. To be honest it is almost a "cool geek" thing for me now. I mean everyone and their mother knows C++ or can create a website. Those just aren't as geek as they used to be.
The two u-controllers (microcontrollers for the slow people) that I learned assembly on are the Motorola 68HC11 and on a fairly standard PIC, which one exactly I worked with eludes me at the moment. The half of a language I know is from the MIPS64 family of processors. I only know "half" because I sort of picked it up as a result of another class and have never actually used it myself.
The language I am hoping to learn is the x86 assembly language. It seems to me that of all the u-controllers and processors the one that is by far the most common is the x86 architecture. I can think of several good reasons for individuals to learn assembly language:
- Quicker and Neater then most compiled codes
- Above makes them better for fast embedded systems
- They teach good programming skill
- Can be more powerful, especially when you know how to use it
It isn't exactly as much needed since most u-controllers have C++ compilers written for them. However, sometimes this compiled code is not as fast if it would have been written in assembly by the user. I hope for the sake of programmers and Electrical/Computer Engineers (like myself) that assembly stays around for a long time. It is still the basis for design of any microprocessor and so long as they are using assembly at a basic level, then people need to know how to use it."Some days you just can't get rid of a bomb."
the key to that article was the word "mastering". Anyone can learn assembly but it takes years of practice to master. Just because I can code in asm doesn't make me good at it. An investment that could be better spent elsewhere on other programming languages
did you forget to take your meds?
A solid knowledge of assembly, file formats, calling conventions, and other voodoo is the price of admission if you need to find out how something works and all you've got is a binary.
In this case I think the reason was the system having to load the binary vs. the script interpreter already being resident in memory. The start up overhead dominated the actual runtime overhead - binary searchs are very quick.
You can check it out here
I've spent the last few years trying to UNLEARN this useless habit [of writing optimized code]. There is just no need.
Tell that to my P166/48MB server.
This is a bit of a digression, but I'd like to point out that not only is assembly useful to implement games, it can be a game in itself: 7th anual International Functional Programming Contest, CoreWars (though I don't expect them to displace the market share of UT2004)
-jim
That set up many 3-4am debugging sessions.
Look, exposure to low level languages and limited memory make you think about what you really need in the program and what you can do without.
In one shop I would take code from the consulting firm, trim out 40-60% of the code, and end up with a job running 25-35% faster (and cheaper). And then there was the other bug in the code. 50 lines of useless code in each of three programs was costing the company $60K in usage to a department per year!
Or how about added transfer time into an EDI program twice for each item calculated. It was causing Disney to hold $10 Million in the warehouses in inventory until I found it.
And it isn't just assembler. It is low level DBMS functionality too. I had one job where the first test ran 12 hours. By re-coding it in a completely different manner it took 5 minutes. The 12 hour method was the method recommended by the vendor of the DBMS. The 5 minute version was mine.
Finally, code can be in a high level language and still be efficient. And there are still plenty of devices out there with limited memory - how about PDAs? or Dive Computers?
- He faults inefficient coding for the failure of software speed to keep up with CPU speed (or at least, its a "large part".) This is much less true than he lets on; Amdahl's Law means that the CPU is less and less responsible for the speed of an application, while things such as disk seek/transfer times, memory access times, and network latency all play huge roles in the speed of your computer's software.
- He seems to think that it's not terribly hard to become an "efficient" assembly language programmer. Bzzt, wrong! In the modern era of superscalar architectures, pipelining, processor specific instructions, branch delays, and memory heirarchies, it takes a hell of a lot of knowledge and experience to beat the performance of a good compiler.
- He apparently hasn't tried any large assembly language porting efforts lately. I'd love to see the effort involved in porting a large x86 assembly language program to a MIPS architecture, all the while maintaining that coveted "ultra-efficiency". The reality is that a good compiler can be reasonably efficient at porting a program to a new architecture, while a programmer usually isn't.
- He also apparently hasn't tried debugging a large chunk of assembly code lately. It is a fact of life that it is very difficult to debug assembly. By using a high-level language, you are increasing the readability of your software, which tends to decreases the number of bugs.
I could go on, but needless to say, I'm not impressed with the numerous assumptions and generalizations about assembly that he makes. Learning assembly will make your high-level programming better, and limited use of it can be appropriate, but using it all over the place is a huge mistake.
It doesn't matter what language you know, crappy programmers will always write crappy programs.
A bad assembly programmer will write unreadable and unmaintainable code.
A bad C programmer will write unreadable and unmaintainable code.
A bad Java programmer will write unreadable and unmaintainable code.
A good assembly programmer will write beautifully elegant and efficient code.
A good C programmer will write beautifully elegant and efficient code.
A good Java programmer will write beautifully elegant and efficient code.
Learning assembly language will help you understand how the guts work, and yes, it can be used to optimize the last 20% that compilers can't do (ie for embedded and graphics). It will help you crack registration keys, solve stack bugs, and write viruses because you will have a better understanding of why certain behavior is prevalent in computer code. But you don't absolutely require it to write efficient and clean code.
Having said that, knowing assembler is useful because it teaches you how the machine works.
However, most modern compilers can generate code that is much faster than handwritten assembler - especially because they know how to take advantage of the specialized processor architectures (hyper-threading, pipeling etc).
...richie - It is a good day to code.
I've been reading this site since it was chips n dip, but this is the first time i've ever felt the need to comment.
I can't believe that any developer could write and code without some knowlege of ASM. Disclaimer: I'm self-educated, so have no bias except my own.
More importantly, if you don't know ASM and can't understand machine language, you'd never get through Knuth's tome "The Art Of Computer Programming".
In my opinion, this is the most important work ever written in our field. Any developer worth his/her salt should have at least read and understood these books, and completed at least the simple exercises.
the examples in tAoCP are written in machine language for a fictional machine, but the depth one learns by reviewing what that machine does with its data is important in any project.
I've never programmed professionally in ASM. infact, i usually work in Perl/PHP/Python. But i would not be able to write quality code in those languages if my mind was not constantly thinking of the machine. After all, i'm a computer programmer, not a linguist or scientist.
Not knowing assembly, or at least having some idea as to how a computer processor works, would make a programmer useless in my eyes. leave them to Access or VBA, and leave the coding to us pro's :)
I beleive that ASM should be taught first. If you can't understand ASM, you'll neer be a good programmer, so why bother learning Java/C++ or whatever? would you trust a doctor who didn't know how the body works?
drewcOpen Source Business: The Tech Co-op
Drew Crampsie - Software Developer
Open Source Business : The Tec
One thing that many programmers take for granted these days is that compilers produce correct code nearly all the time. They've gotten really good over the years and are really a testament to the quality of compiler engineers. Even so...
I've been a programmer for over a decade and I've always found the worst problems to debug are when the problems aren't in your code but in the compiler. Compilers are programs too and have their own bugs. They aren't always 100% accurate at generating correct machine code for your source. And until the compiler gets fixed in the next patch or rev, you may be stuck with broken code unless you switch compilers.
Sometimes disassembly of the problem code and inlining correct assembly can be the difference between shipping a product or missing a deadline because you've spent months sitting around for the next compiler version to fix your problem for you.
ed
Comment removed based on user account deletion
I didn't start programming until I was in my mid 20s (degree in Chemistry). I liked fiddling with Java but always felt uncomfortable about what was going on underneath the hood. So I took a few classes. The first was Computer Systems Architecture. We wrote a game in x86 assembler. That class completely opened up my understanding how programs actually worked. To understand the stack, the state machine nature of things, and memory was an awakening experience.
Now (~5yrs later) I'm a fully capable programmer and an even better designer. My preference is C, binary file formats, networking protocols, crafting elegant solutions for multiplexing IO. I'm lead on a project used in production by many companies large and small.
I genuinely feel assembler is a vital part of the learning process for a programmer.
Well, I'm a recent (May '03) computer engineering graduate. We programmed in assembly on MIPs, x86, Motorola, and several other architectures that aren't coming to mind at the moment.
The CompE curriculum at my university was very electronics / hardware oriented, so there was quite a bit of asm to learn. Not to mention VHDL, etc, which is also quite valuable stuff to know. Nothing like building individual logic from scratch and putting it together to simulate a microprocessor. Then trying to implement it on a chip.
A preposition is a terrible thing to end a sentence with.
I wouldn't dream of programming an application today in assembly language.
Yet at the same time, someone who has been exposed to assembly but can not code in it... well, they probably can't really code in any language.
Being language agnostic is important. Sure, you can prefer to code in this language or that, but if you can't sit down at a new language and learn the basics in a few days you're not that talented, really.
I see a meta-assembly being useful today; a simplified instruction set with emulator that needs to be coded using a very simple set (say, less than 16) instructions. This would be a great way to cut your teeth and learn how a computer "works." Does it matter that a modern computer has caches, instruction re-ordering and so forth? No. The basics are the idea of registers for working variables, and memory storage as mid-term storage, mathematic operations, and branching.
I don't see learning a particular processor's assembly instructions as terribly useful. My 6809 knowledge is pretty low, and my 680x0 knowledge is even lower. About the only thing I know about x86 is that the byte order is hard to read. :) But I think I'm well served by the concepts I learned. And I think anyone who has programmed a virtual computer with an instruction set of 16 instructions is less likely to be unable to jump from, say, C to Pascal to Perl.
Certainly, the ability to optimize a bottleneck for speed is nice, but I think that's less important than the grasp of the basics.
To summarize that (I guess I went on too long), I see the ability to code in assembly as more important in learning to program (and evaluating someone's abilities) than in making or even optimizing working, non-trivial desktop applications.
I've seen some pretty dumbass code in my day. And it probably would have been easier to spot the guy's lack of talent in a few hours at an assembly level than a month later in a high-level language.
Assembly is still good. It taught me code optimization. If oyu learn assembly you learn to program using as little resources as possible. I think many of today's programs and games could run faster yet if sloppy code would be fixed up.
Given the way processors are pipelined, you take such a hit for any kind of function call compared to a set of arithmetic operations that the only way to go is to call functions on arrays or slices of arrays to process batch of samples at a time. If you implemented a digital filter by calling a function for each sample you want to process, that is going to be slow, while if you call a function for batches of 1024 samples, you are really pretty insensitive to the function call overhead. If the function call overhead is high, just make the batch size bigger.
This arises in other situations: for operations over a network it is recommended to make your transactions blockier or chunkier; for raster graphics, the naive Windows SetPixel() command is slow compared to CreateDIBSection().
I learned 6502 assembly in the 1980's on a Commodore 64. I even have it all imported into my system, into a few D64's full of software I wrote myself - to run in an emulator for old time's sake. (Gee, hard to believe that some of the programs are almost 20 years old now.)
I had a lot of the habits that you describe, and I now program simply in C++ for either Linux or XP.
However, I had run into some performance issues with certain critical loops that were executed millions of times, such as a loop that iterates through pixels in image processing, and I wanted to view the disassembly of it. I understood enough assembly to be able to optimize a tight loop in a plain C code routine, and verified that the assembly was just as good as handcoded non-MMX assembly. (Some compilers do an amazing job now) The only way to improve the performance further in my case, would have to have written MMX/SSE/SSE2 for this 0.05% of a computer program, but even so, I deemed it not to be still worth the effort.
Now, if you are talking about realtime video filters, such as deinterlacing and sharpening (think Adobe Photoshop style plugins executed 50 or 60 times per second for every interlaced video field at 60 Hz for NTSC, 50 Hz for PAL), you still need matrix math operations such as MMX/SSE/SSE2 assembly language if you want to do lots of video enhancement realtime on a live video source.
One example program is the open-source dScaler project - dScaler Realtime Video Processor . You can do REALTIME sharpening filters, denoising filters, motion-compensated deinterlace filters, 3D-like chroma filters, diagonal-jaggie removal filters, etc, all the above simultaneously, on a LIVE real-time video source from a cheap $30 PCI TV tuner card, on today's high end Pentium 4 and Athlon systems. All this would not be possible without assembly language. Now, they are talking about adding realtime HDTV enhancement (1080 interlaced -> 1080 progressive). Run your cable/satellite/DVD box connected to your home theater PC running dScaler, and hook the home theater PC to your HDTV, and the live homemade "upconversions-on-the-fly" you are seeing are shockingly better looking than the bad quality upconvered video you watch on TV; (Important: Don't use S-Video output, connect the VGA output directly to the TV using a component-output adaptor. It's 6 times sharper than S-Video. For more information, see AVSFORUM's Home Theater Computers Forum section for more information about getting HDTV-quality video out of your computer to your HDTV television, especially if the HDTV television does not have a native VGA input.)
(For watching live realtime videoprocessed video, I don't recommend a $30 TV tuner card, the power users like to get more expensive cards such as approx-$250 PDI Deluxe card, which is a Conextant 23882-compatible card that actually has a Y-Pr-Pb component input for computers! Supposedly better analog signal-to-noise ratio, better A/D converter electronics, better power filtering.)
The point is that you don't need assembly language most of the time, but there definitely sure are times that it's exeedingly, absolutely critical.
well so? - that proves nothing. To make any sort of usefull point you have to compare the same things.
In reality carefully hand crafted assembly will usually beat compiler built code (not always there's always that superoptimised goodie you never thought of) .... but it's seldom worth doing the hard work ... the real trick is to have done enough of both to be able to decide when it's worth your time to tune something (and what to tune)
an efficient algorithm coded in an inefficient way will always beat out an inefficient algorithm coded by hand in 100% optimized assembly.
Big fat hairy deal. An efficient Schwinn bicycle could outrace an inefficient Harley-Davidson motorcycle, given sufficient levels of efficiency, so what's your point?
The fact remains that an efficient algorithm coded in 100% assembly will still beat the same efficient algorithm coded in Javascript.
Don't blame me, I didn't vote for either of them!
The author of the article is obviously biased, and completely wrong. Laboring to improve execution time by a (small) constant is the epitome of inefficiency -- more important is chooosing the correct algorithm and data structures. Nowadays, this often means using hashtables everywhere. Try doing this in assembly, supporting arbitrary data types -- I'd rather let the compiler do all the work.
I agree some "under-the-hood" knowledge is often helpful, but assembly is only really useful for that sort of knowledge in limited areas, primarily low-level stuff. Much more useful in most systems is knowledge of the system components at a level higher than the CPU--details about how the OS works (scheduler, memory management, etc.), how the language you're programming in is designed (is tail-recursion done without a stack? is list concatenation faster from the front or back? etc.). Knowing assembly will do much less for your LISP code, for example, than knowing how your LISP compiler is implemented will.
10 PRINT CHR$(205.5+RND(1)); : GOTO 10
...
If you don't understand what's going on at the machine level, you are going to run into trouble eventually because your perception of the runtime environment is slightly or even wildly incorrect.
Example: When programming in languages like C or C++, you have to know what a stack frame is and basically how it's implemented, so that when something goes wrong you can correctly diagnose the problem. If you just know the corresponding language syntax (i.e. the scoping rules), you won't have the first clue where to start.
This applies to Java as well - just replace "machine code" with "bytecode" and "CPU" with "virtual machine".
In all these cases, a compiler takes your program specification (the source code) and produces the *real* program (in machine code or bytecode) - and that is what is executed and that is what you will be debugging and analysing. If you don't understand basically what machine code is and how it works, you will keep running into brick walls. I've seen this over and over again - the new graduates who just can't see why their program is behaving the way it does, because they never did assembly programming, or studied the run-time environment of programming languages, and so have these bizarre ad-hoc mental models of what's happening that bears little or no relation to reality.
I'm not saying that assembler should be used any more than it is currently, but if we are going to be using compiled languages (C, C++, Java), then it simply *must* be taught. There is simply no way to avoid this if you want to be a half-way productive programmer in those environments.
Where are my mod points when I need 'em... It is actually FUNNY (+1)
Paul B.
Sorry if I seem snarky but I feel that many of my fellow posters are missing the point of this discussion. At issue is not necessarily the question of exactly which things should be written in assembly code (or not) but rather that the experience of learning to program in assembly is a valuable one. I noticed an improvement in the overall quality of my code during and after taking the assembly programming class that is still required for computer science as well as electrical and computer engineering majors at CU Boulder (I am one of the latter).
The debate about whether assembly code really provides an appreciable gain in performance in certain areas, or if the gains realized through assembly programming are worth the costs in time and flexibility, is an important and necessary debate. It is not the most useful discussion that could take place at this time however.
Assembler is used as a weed-out course. This course humbles a lot of hackers....
The society for a thought-free internet welcomes you.
No, you're the one without a clue. Read his article. He is saying that it is useful to *learn* assembly, not that it is useful to use assembly for everything you write.
Don't blame me, I didn't vote for either of them!
Dude, get the fuck outta my head. No, seriously, I'm kreepin' me out. Get outta there.
This whole "no one's teachin assembly like they did in the good ol' days when men programmed in assembly and panzies toyed with compilers" is overblown. Assembly programming in the university setting has been losing ground, but only in the way of dedicated assembly classes. Students in a good program will undoubtedly encounter assembly during their education as there is still no way to teach a topic like computer architeure or compilers without covering assembly. If a person could do anything to increase his/her coding effiency it is take a few compilers classes. The optimization algorithms in these classes are the basis for essentially all the smart coding tricks you can find as optmization was the main focus of compilers research up until late. For example, the generalized code motions alone cover a number of the these smart tricks. Moreover, learning these algorithms let's you quit wasting time hacking away at some of the optimizations, like some tail-recursions, that your compiler may already be able to do.
A non-hardware type can learn alot about how their hardware works by programming a few short assembly language programs. Jumps, registers, memory layout, etc.. Great exercise.
The heat from below can burn your eyes out
If you want to do ASM use it where it fits. Not programming an x86 box with a Gig of RAM and a hard disk. No, work with 8 bit micros with tiny amounts of RAM and ROM. On these guys with 4K ROM and 256 bytes of RAM using ASM is fun and it fits. Also both the architecture and instruction set fit in your head so you can and do truly think like the computer. There you see the purpose of special instructions like bit test or bit set and appreciate using the right branch instruction to save a byte. Also you get to see directly the consequences of the chip architecture. I remember going from a 6800 to a 68HC11 and being amazed what I could now do since I had two index registers.
Also working with ASM gives the programmer a great appreciation of code and data structures. It still amazes me how many programmers can not see the connection between ASCII 'A' and 0x41, or that 0-9 in ASCII is just 0-9 + 0x30.
Finally, optimization, small machines force it on you. Fill ROM but need more code, go back and optimize to get the space, rinse repeat... I found that you could usually get 15% on the first pass, maybe 5% on the second, then it became a matter of bytes after that.
Ah, the good old days.....
Why learn assembly?
Because most people don't understand that a computer is a COMPUTING MACHINE. Many coders don't understand how a computer actually works.
I want my rights back. I was actually using them when our government stole them after 9/11.
Several books I have sitting on the shelf over my monitors - that I occaisionally peek into:
Sparc Architecture, Assembly Language Programming & C - Paul - Prentice Hall
Using Assembly Language 2nd Edition - Wyatt - QUE programming series
Turbo Assembler 3.0 - User Guide - Borland
Mastering Turbo Assembler - Swan - Hayden Books
Peter Norton's Assembly Language Book for the IBM PC - Revised and Expanded - Norton & Socha - Prentice Hall
Ahhh - reminds me of the good old days! Back when Real Programmers roamed the Earth...
Lodragan Draoidh
The more you explain it, the more I don't understand it. - Mark Twain
Due to the advancee in hardware capabilities Bloat is now excusable - and encouraged. It is cheaper to buy a big ass computer that can crank and hog bits than it is to pay somebody good money to nitpick over every bit of resource that their programs consume.
;-) ) SEVERAL computers? I may be mistaken, but I do not think that you still have the mentality of "The world's market in computers is probably 5 or 6 of them" (food is burning on the stove, no time to get the exact Watson's quote ;-) ).
;-)
What if you want to run your app on (God forbid!
Last time I checked the price difference between a $100 ARM-based unit and $5,000 G5 was still $4,900, so if you intend to run your program on a 1000 units you can as well pay $900,000 to a guy who can port from the latter to the former and keep the cool $4M.
Or if you think about selling your solution (HW+SW) to some millions of customers... (Wow!)
Paul B.
I write my code right the first time. :)
Fight Spammers!
Another reason why assmbler will always be useful is that many CPUs have valuable instructions that have no C equivalent. Therefore to use these instructions one typically needs to write assembler.
Frequently it is simpler to write a function that accesses hardware directly in assembler than it is to write it in C. With C the compiler will often jerk you around and optimise away specific behaviour that you want.
Engineering is the art of compromise.
(Almost OT)
Maybe someone can point out to me ignorant, why - when I learned Assembler on PDP11 25 years back, it was Assembler and today it is Assembly instead of Assembler ?
Thanks !
Much more useful in most systems is knowledge of the system components at a level higher than the CPU--details about how the OS works (scheduler, memory management, etc.), how the language you're programming in is designed (is tail-recursion done without a stack?
Of course, some of these, even if you don't HAVE to know assembly language to understand them, knowing assembly language makes it easier to understand. Most people who know assembly language have a much more concrete view of the differences between pointers and values. When you have personally had to think about whether to push the value or the memory location, when you have to think about which addressing mode you need to use in that situation, it makes the idea of pointers and stacks and calling conventions a TON more concrete. It also makes many of the ideas of sequencing and linearity a lot more concrete. This is something that I've found a lot of new programmers have difficulty with - they have trouble thinking in straight linear fashion, and assembly language absolutely forces you to think that way.
Anyway, that's the reason I wrote my book on assembly language. See my sig for more info. Randall Hyde actually wrote me a pretty good review on barnesandnoble.com. I got a good one from Joel Spolsky, too.
Engineering and the Ultimate
I agree with the premise of the article and I understand the logic behind his arguments. I too, believe every programmer should have a strong math foundation and learn assembly language - regardless of the architecture. Generally speaking, knowing the "nuts and bolts" is what separates the 4-year CS degree programmers from the 2-year, fast-track-to-developer "programmers". All too often schools do future developers and the companies they end up working for a disservice by churning out less-than-ready programmers with a weak foundation in the why's and theory in exchange for a bunch of how-to's on a particular language syntax.
However, regarding the article, there's a piece of the puzzle missing. In the case of a byte-code language like Java or C#, the code isn't compiled to assembly or machine code where it's easy (other than a debugger disassembly) for a developer to get at. In the case of C# or any other .NET CLR language, it's nearly impossible to know how the compiler generates assembly instructions. In the case of Java, one may be able to study the JIT compiler of an open-source implemenation like Blackdown but that's not necessarily the best option or even the most efficient implementation either. There are so many different JIT compilers for Java, which one would you study? With the .Net CLR, the only possibility would be to study the source to ROTOR to gain any insight into the JIT compiler.
The implication of the article is that the programmer has some access or insight to the compiler output other than looking at the object files. I submit that, especially in the case of a byte-code language, that insight isn't nearly as available. After all, we're talking about programmers that don't know assembly, in all probability don't know what an object file is, and perhaps don't have the expertise to know how or where to garner such information.
I would like to see these programmers learn the difference between the stack and the heap. It's not exactly easy, especially when you don't know where to begin, to figure out how the compiler for a high-level language creates assembly instructions from source. Learning that information (think YACC and Bison) is on the same level as assembly, combinatronics, and two's complements. Again I say, it's not enough to learn assembly - Without the solid background in math, data structures, and other concepts, the 2-year degree programmer is, in all probability, lost. You can't learn or use assembly without two's complement, binary, and hex arithmetic. How could you figure out how to add 64-bit numbers when you only have 32-bit registers?Like I said, I don't disagree with the premise of the article. However, simply learning (or trying to learn) assembly is not the cure-all for all programmer deficiencies. You just can't take a person that can't add 2 hex numbers, run them through assembly 101 and expect the Mona Lisa of software. I suppose there are broader implications to learning assembly like having to learn all of the aforementioned skills first but that was never indicated in the article.
If you do what you always did, you get what you always got.
No YOU get out of OUR head, it's crowded enough already in here. Don't make us get violent. Because that would be painful. And I know how we love pain. And assembly. And naked chicks with large breasts. And star trek. And periods.
"... drowning in information,
The As I've said before, a good mechanic can tear down and reassemble an internal combustion engine, and that my argument is that a good programmer can do the same on an ASM level should the need arise.!
/. uid, after all... ;-)
but, OTOH, you do have a 4-digit
Great symphonic programming masterworks will always be scored in high-level languages. But there are those of us minimalists who thrive on doing as much as we can with as little as possible. Writing a tightly-orchestrated fugue for an eight-bit microcontroller in assembly language is an art form I shall never grow weary of practicing. With a 2K program space and maybe 128 bytes of RAM, every single note must contribute to that ephemeral interplay between space- and time-efficiencies. Those of you who do this for a living will know what I'm talking about. To those just entering the field, I hope you seize whatever opportunities you can to learn assempbly language -- especially if it's for a low-level controller. You may become hooked for life!
I still think that it's extremely important for a programmer to understand what's happening at the lowest level in the target system. It's also very important for low-level work such as bios code and for small system programming. On some small embedded systems, a programmer can actually be concerned about efficient stack use, etc, and if you have limited RAM, the bloated spew that a C compiler puts out just might not be acceptable.
Understanding of assembly / machine code can also be quite important for hardware people. Example: when debugging a new board design with a logic analyzer hooked up to the system's buses, C/C++ knowledge isn't going to help decipher that long list of numbers being transferred from RAM to processor.
Mastery of assembly is completely pointless for anyone outside of OS kernel, compiler construcution and embedded development...which probably means you.
.com collapse).
And why do you think that in a year or two the Si wafer real estate (or, more realistically FPGA real estate, which it is probably right now) will NOT become cheap enough that one who thinks of himself as a 'programmer' now would have to actually write VHDL for the processor part, then assembly glue, and only then port Linux to the "ultra-optimized to track your eye movements while simultaneously scanning your brain waves for the tune you'd like to listen to now" car-dashboard computer?
The line between hardware and software is disappearing, and producing way too many "programmers" who can only code Java is a sure way to the next economic disaster in this country (way worse than
Are you sure it is not happening?
Paul B.
Which "real world" are you talking about? The real world sitting on a desktop or the real world in a modern fighter jet that can't be flown unless computer software is used to keep it stable? Where time concerns are critical and every last machine cycle counts. Welcome to the "real world" of hard real-time computing. Where a slip in time costs lives. Profilers can't be used here because they increase execution time.
Or how about in the embedded "real world" with 64K (that's 65,536) bytes (or less) of program code space and 512 bytes (or less) of RAM? Believe it or not, there are literally thousands of these computers for every desktop computer on earth. Where not ony time efficency but cost and power consumption (lower speed processors), code and data efficency are critical. Profilers aren't much use here.
It may also suprise you to know that some compiled programs do run time CPU type checking and use different code paths depending on the results for exactly the reasonds you give. A profiler can't always help produce code that is efficent enough on all the variations of the x86 CPU architecture. Few programs need this level of efficency, but when they do, there are few alternatives.
And, last. No compiler can produce realy good optimized code without a programmer with an intimate knowledge of the instruction set and hardware architecture of the processor the compiler is producing machine instructions for.
Maybe you need to learn more about "other" types of "real world" computer software uses before you shoot your foot off talking about subjects you clearly do not know enough about.
Can anyone recommend some good Assembly books? x86 please. The Art Of Assembly seems too high-level.
Its not that I do not agree with Randall's comments, as I started out writing assy on 4 bit cpus (don't laugh, 20 years later they still make millions of them a year), but the 'article' is nothing but a sell pitch for his book. Hopefully OnLamp.com charged him to 'post' that 'article'.
Well, the real world I work in, OS development, I write or read assembly every day.
What you are advocating is that the students should understand the cost of the code that they write and you are saying that understanding assembly is the way to do that.
But here is where you are missing the point.
It is not the only way and sometimes it is the wrong way.
With virtual machines and interpreting languages, knowing the machine code of the CPU becomes pointless. You need to know what is costly for _your_ language.
What I think that you _really_ meant was that your students should understand compiler technology. That is how you understand the cost of different language constructs in a way that is portable across compiled, interpreted and byte code languages. This is unfortunately not something that you can have beginners learn, it is more of a third year thing.
Also, I've programmed professionally for 10+ years in most programming languages known to man, and I agree with your parent poster. Write simple and sensible code. Optimize when needed. More often than not, you will find that the code is fast enough. If it isn't, then you saved so much time writing the code originally, that you can spend a lot of time optimizing the problem areas.
If you disagree with this approach (write simple code and optimize when needed) then I'm willing to bet that you've never programmed outside a university environment.
The Internet is full. Go Away!!!
If I may quote him:
"Unfortunately, when software performance is less than optimal, these programmers generally don't know how to correct the problems with their software. They'll often spout things like "The 90-10 rule," or "I'll just use a profiler to correct the performance problems," but the truth is they don't really know how to improve the performance of their underperforming applications. It's all well and good to say, "I'll just find a better algorithm!" However, finding and deploying that algorithm, if one actually exists, is another matter."
That's where he covers profilers.
"Most of the time you can achieve very good performance boosts by simply improving the implementation of an existing algorithm. A computer scientist may argue that a constant improvement in performance isn't as good as, say, going from an algorithm with O(n^2) performance to one with O(n lg n) performance, but the truth is that most of the time a constant factor of two or three times improvement, applied throughout a piece of software, can make the difference between a practical application and one that is simply too slow to comfortably use. And it is exactly this type of optimization with which most modern programmers have little experience."
That's where he claims that his concept is better.
I must disagree. Without having any resources, I would suggest the bulk of software developers are building business applications. You know - the non-computer science stuff. Not compilers, not operating systems, not the latest whiz-bang game, etc.
A number of us are true computer science students, and we cut our teeth in assembly, so-to-speak. That being said, I disagree that it is necessary (or even good) to understand the machine at the low-level. I have never done x86 development (instruction set and memory models never made sense to me) and I have never seen the JVM byte-code that I use daily. Nor do I care to.
If you're writing code that is supposed to be optimized for the machine, you've missed close to a decade of compiler development. Dealing with multiple pipelines, delayed branching, etc is best left to a machine. I have more pressing issues to solve - like delivering good software.
The compiler optimizations are pretty astounding today. The JVM run-time optimizations are amazing. My knowledge of hardware architecture is 20+ years old. I'll trust the compiler writers as well as the JVM designers.
The focus for the bulk of us is on maintainable applications that can be delivered "on time, within budget, blah blah blah." Illogical algorithms and/or writing code for the computer and not for the human don't help anybody. In fact, I'd probably just throw it out and start again - it's the fastest and least stressful way to deal with it.
The most important tool to hone and keep tuned is your mind. Those with good logical reasoning and critical thinking are going to do well. They are the ones *I* look up to.
I would suggest teaching unit testing (ie, JUnit) - including what to test and how to test correctly (both difficult topics) - and debugging skills (which I wished I had more of when I started) instead.
If you want to cover hardware, use a book like CODE (by Charles Petzold) to give people an idea of computer structure. Nothing more than that - and even that isn't required.
In my undergraduate computer science course, I managed to learn assembler twice and bytecode once: Assembler for a simple simulated processor (1988) This was the first module in one of the two first-year courses. Pascal was the first module in the other first-year course. 68000 assembler (1989) "Eventually, all languages are reduced to assembler. And sometimes you will use it for speed." EM, an intermediate language - the bytecode (1989) Part of a compiler course. I haven't worked on compilers, but it was incredibly useful when Java came along. I'd recommend this to anyone studying computer science, or anyone designing the course programme.
Actually, there's a Perl module that does this. But if you wanted to write said C program from scratch, it could take you a while--writing the Perl program would be much faster. And then there's the choice of algorithms involved. Have fun writing your own sorting functions in C, your own regular expression library in C, your own arbitrary precision number library in C, your own reference-counting garbage collector in C, your own closures in C...
:)
Of course, there are other pre-existing C libraries you could use that do all of these things, but there's no telling whether or not they're faster than what Perl uses internally, and since you're re-implementing everything in C anyhow, you might as well just write your own!
So the point I'm trying to make here is this--Perl is convenient because it has all these things written for you and integrated together. Sure you could write a C program that does the same thing, but you'd end up re-inventing the wheel many times over, and you'd have to work hard to make it a better wheel.
Or you could target Parrot instead, for a lot of things it's already faster than Perl. It also has a JIT compiler, so who knows--it might generate some code here and there that's faster than what your C compiler generates.
pb Reply or e-mail; don't vaguely moderate.
I thought it was understood that knowing a little assembly makes you a better programmer. Not that I know as much as I should, but it's been useful.
;) You shouldn't use the "engineering" tagline on things that don't actually use the principles of engineering.
On the other hand, it's important to distinguish between software engineers and code monkeys. Cobbling a bunch of keywords together that can compile (heh, if your language even compiles) does not constitute crafting software. A lot of people who think of themselves as programmers are much closer to "power users" than programmers. Not to bash those folks, but the industry should understand that difference well enough as to not try to write realtime life-critical code in visual basic
In short, in C you should be able to produce good and clean code that tells the compiler how the machine should perform the job, rather than saying only the "what" part (which is hard to express well, precluding many optimizations) vaguely and rely on the compiler (which does routine jobs such as register allocation well, but is not that clever) to figure out your exact purpose.
High level languages (such as Lisp/Haskell) are currently different. Since they are so high-level, and the compiler isn't clever enough for it (so that it can optimize away some type-checking, lazy evaluation and do some function inline which is essential for acceptable performance sometimes), you often have to write code in a not-so-beautiful way if the speed matters a little. That's my pet peeve against such languages which makes me reluctant to use them if the resulting code is going to take more than a few seconds of CPU-time, although I love them dearly otherwise.
Not only should the programmer learn assembler, they should also learn Operating system mechanisms. So they understand how their program is operating relative to those mechanisms. but that is not enough, they should also learn CPU design. How else are they really going to understand? Actually they really need to learn about materials science. Not enough really is it? Physics, laws of thermodynamics, electronics, quantum theory. Then when they program they will *really* know what is going on.
Alternativly they could learn more about the problem domain, so that the design better reflects the problem domain and will be more flexible in the changing environment. Nah, that really would be a waste of time.
I suggest you watch this presentation on the Psyco just-in-time compiler for Python and do some research on the Transmeta Crusoe processor to learn about run-time optimization.
On behalf of all decent programmers on the planet, may I say..
DUH!
Imagine a mechanic who has built his own engine from scratch, or a painter who has made his own paint, or a musician who crafted his own instrument. Those seeking to exercise their art on the lowest possible level will always have superior insight into those that don't.
I think coders are more efficient in assembly because they don't want to have to write 54 lines of code to do something when if they consider the problem they are solving, they could write it in 10 lines.
Yes, if you're programming for popular UNIX or PC platforms, ASM really can't gain you much. Many free compilers already come with a strong set of optimization rules that can pretty much match handwritten code. And really, you have to go out of your way to write horrible code that translates poorly. I mean, compilers these days are pretty good about caching expression evaluatoins and inlining function calls. Where assembly language really counts is those instruction extensions. Especially with older compilers that maybe you haven't bought the new version of (why you're paying for one, got me). Fortunately, most people who need instruction set optimized code often turn to libraries written with that specific purpose in mind. There's a couple MD5 libraries for sale that have mmx, sse, or sse2 optimizations, for example. So learning ASM probably won't help you write faster code for your desktop, nessecarily.
On the other hand, a large quantity of high paying software engineering jobs don't use the UNIX or PC platforms. PowerPC's often have specialized hardware that you want to access, as do several other kinds of boards and microcontrollers. Furthermore, you might not even have a C compiler target available. And even if you do, it's almost certainly not as dependable as gcc. In this arena, knowing how to write and read assembly code is vital. Hell, when I wrote the code for my selective weed sprayer, it read pretty much like ASM would. Set a few register values, read some other ones, then reset a timer to do it again later. And when it doesn't work, its often helpful to check the ASM output to see if perhaps something's going wrong either in your mind or the compiler's mind =).
I Browse at +4 Flamebait
Open Source Sysadmin
In the UCK language, you can have filenames like d.uck
Well, you could if there were such a language.
Old people fall. Young people spring. Rich people summer and winter.
I wrote a C# performance comparison tool to help me in this respect. When you're trying to optimize a hot-spot in your program, you can click on the "ILDasm Result" tab to see how .Net compiles it down to its Microsoft Intermediate Language (MSIL) representation.
I've also got the book, "Inside Microsoft .Net IL Assembler" that's very helpful. For whatever reason, you can get it for like $2 + shipping used from Amazon.
It all goes downhill from first post
SO WHAT! Programs should only be optimized if:
1) the program is doing stuff so intensive that it runs slow
or
2) It is being run all the time in the background by the system and can slow down the system as a whole.
98% of the time it just does not matter.
I agree with points 1 and 2, however, if you're doing any non-trivial programming, I wholeheartedly disagree with the 98% figure. Not every bit of code is a throw-away piece. If your code only runs occassionally, and it's not performance critical, then yes, make readability your main priority.
But a lot of times your code is performance critical, or at least will be in the future. Code has this tendancy to stick around once it's actually working. Too often have I seen code that, when it was written, was not getting used a lot. It worked, so nobody thought anything of it. As they scaled the system up, that code became a major bottleneck and eventually somebody had to go back and optimize the hell out of it, or simply throw it out and rewrite it to be fast.
It's good to write readable code. But it's also good to write code that is reasonably optimized at the same time. No need to go to extremes, just don't do stupid things like passing around huge 4 kilobyte variables to functions and such (example I've seen). Pass a pointer instead. Or a reference. Just write smart code. You can still make readable code while making it optimal enough to scale pretty well. Only very, very rarely do you have something that needs to be super well optimized, and then you usually are better off writing the critical sections in machine code anyway.
Easilly readable code is FAR MORE IMPORTANT.
Easy readability is far more important when that code scales to the level you need it to scale to. Readable code that doesn't actually work in the system you're trying to put it in is worse than useless.
- Give a man a fire and he's warm for a day, but set him on fire and he's warm for the rest of his life.
Learning assembly, even if it's not on your platform, is good mainly because it imparts discipline. That doesn't mean you have to hand-tweak and optimize every freaking line of code.
But what it might get you is the ability to make those little decisions with a bias towards effciency. When you write a function, there are hundreds, if not thousands, of little decisions you make. Inline it or break it out? Put it in a loop, or break it out of the loop? How many calls might that be?
All these little things add up. If you understand how the compiler optmizes (for example, hoisting or CSE) you can do it yourself and save a little time. A little time here & there add up.
For example, positive loop tests should be first because almost every CPU branch-predicts on the positive case. Doh!
Hoist constant expressions out of a loop. Why not? Your Java compiler is usually too dumb, it might save a lot of time.
You can also do stuff in Java, too. Check the output - did you know references to an object's instance variable is more expensive than copying it locally to the function? Save a million cycles in a big loop.
It's not like thinking like this is hard, once you've done assembly. It's kind of automatic. It's also hard, because you have to do only as much as necessary, not more.
Many posters seem to be promoting compilers over learning the nuts and bolts of a particular architecture yourself: somebody had to learn it to write that compiler! Probably a whole bunch of somebodies, because writing a good compiler is a hard task.
Even then, if you don't understand how your language is compiled, you cannot properly debug your code. With C/C++, it isn't just a case of stack frames, there's memory allocation, pointer dereferencing, etc. Sometimes you need to look at the assembler level to get a grip on some bugs.
I know from experience that compilers are buggy, don't perform the same way with the same switches on different platforms and while they may optimize generally better than a human, sometimes it's a bug to optimize at all!
Some appreciation of the assembley level is better than nothing at all.
insecurity asks the wrong question irritation gives the wrong answer
Shipping software is all about where the rubber meets the road. It's important, especially when it comes to debugging and handling bizarre crash conditions, to know what happens at the most elemental level.
Best Buy can have you arrested
Every shred of C he's ever written is absolutely unmaintainable. It's just horrible.
The answer to the question "Is assembly language faster than C?" is the same as the answer to "Is C faster than assembly language?": "No." My point is that there's no magic bullet. The article was not nearly balanced enough to be considered correct.
You're mixing examples. In the first, we're talking about an interpreted language being written in a compiled language, and whether or not the interpreted language can still be faster.
You're talking about a program in an interpreted language that spits out machine code. It's kind of like pretending a horse riding a human is the same as a human riding a horse - although the same two animals are involved in both cases, the overall situation is completely different.
That said, I still say Perl is going to have a darned hard time being faster than C since it has to precompile the program every time it executes whereas a C executable is already in machine code. Not saying it can't happen, just saying a situations where it happens probably aren't all that common.
I want everyone who thinks this to go out and play the Mac version of Halo. Notice how amazingly slow it is. This isn't because PPC is a slow architecture - this is because the people who ported the program didn't pay attention to the underlying architecture they were porting to.
I'm not saying everyone has to be a hardcore assembly programmer, but I am saying understanding assembly and the underlying architecture on which you are developing software can make a huge difference. The fact of the matter is, an optimising compiler is not a magic bullet any more than anything else is a magic bullet. The optimiser is great for doing the real low-level instruction shifting type optimizations that a lot of people think are the real optimizations.
But the optimiser can't help you with poor data structure design, poor memory access patterns, or any other of a host of high-level decisions that still have a lot to do with architecture.
It's not about hand-optimised assembly anymore, anyway - at least, not if you're working on a beefy architecture with out-of-order execution and all that. But you still need to have a general idea of what kinds of things your particular computer does well and what kinds of things it drags ass on, otherwise you can still end up writing your own little version of Halo PPC.
Knowing assembly is useful. Assembly itself, as a general purpose language, is pretty much useless. A programmer should intimately know his compiler, and what sorts of machine code it generates, and then just write in the high-level language, confident that his low-level knowledge will allow him to coerce his compiler into generating good code.
A deep unwavering belief is a sure sign you're missing something...
If 640k was really enough then why need 128mb just to type a damn paper in Word?
Passing 10 argument is bad regardless of the performance issues. These students are making a much more fundamental mistake: they're not dividing up the problem properly into easy-to-understand pieces.
A useful analogy (but don't take it too literally cause I'm oversimplifying it): verbs in natural languages never have more than 3 arguments (subject, direct object, indirect object). If you find yourself crassly exceeding this, you need a justification.
Are you adequate?
I have seen this attitude destroy companies while their competitors were able to implements features based on advanced algorithms, data structures, and knowledge of the underlying hardware. I think the only reason it manages to persevere is that so many companies do not need to rely on advanced technology for a competitive edge. It's probably also the reason that I can't manage to find a single bank that I would consider competent with regards to their computing infrastructure.
I tried learning assembly language, but the I can't find ne place that will really explain to me the details of how it works, I'm afraid I don't know enough of the computer engineering side of it to understand the language. Whats a good place to start, wheres a good tutorial or book? Thanks.
Maybe your algorithms suck, since that's a difference of 2x. Could it be so?
Some people say you need to optimize. Other people say you need a better algorithm. So who's right? Both.
/(.+)\s(.+)\s(.+)/" and "($one, $two, $three) = split ' ', $things". However, knowing assembly does help. Since I know assembly, I know that the latter results in some executions of "scasb" to find spaces, and seperating the string, whereas matching a regular expression is pretty complicated, despite the fact that someone has really optimized it and it doesn't do as bad as it could.
If there's a better algorithm, you need to use it.
If optimizing your code can make it 10 times faster, you need to optimize it.
Now if optimizing your code will yeild less than a 2x increase (with less than simple changes), then perhaps you shouldn't bother, especially if it makes the code a lot harder to work with, but the same applies to algorithms as well. There's no need to implement a complicated sorting algorithm to sort five items, even if it will double the speed.
The problem is people usually don't know that their code can be optimized anymore than they know that a better algorithm exists.
People don't intentionally write slow code, they write slow code for the same reason they use slow algorithms, because they don't know any better.
Just as you should research algorithms for whatever you're doing, you should also learn how to write fast code in whatever language you are using. The only reason assembly language does well here is because more code equals more work for the processor, whereas in high level languages fifty lines code may execute very quickly while one single line elsewhere takes twenty times as long as those 50 lines.
Learning assembly isn't necessary. All that necessary is knowing what the difference between "($one, $two, $three) = $things =~
BTW, a compiler being "optimizing" doesn't mean it creates the best code, it just means it doesn't create as bad of code as it could. You can create a compiler that always turns certain C statements into certain code, then you can make an optimizing one that eliminates some code since it knows that this followed by that doesn't need a few of those instructions, but you can't replace someone who knows what they're doing.
After all, isn't the reason you're supposed to use C's strcat instead of copying the string yourself because the strcat uses the movsb instruction which is faster than any loop the compiler would create on it's own?
Of course, even so, you could still do better using assembly, depending on what you're doing. If you implemented pascal type strings you would remove the requirement of doing an scasb on the strings to find their lengths which you need to do the movsb. This could be a major optimization depending on the size of your strings and how often you're using strcat.
I tried finding a way to profile my code recently. I found AMD's profiler was totally incomprehensible. So I tried to download Intel's, even though I'm using an AMD CPU. Well it was so hard to figure out how to use that the trial expired before I ever got to use it once, and they want some hideous amount of money for a version that doesn't expire.
Introducing the new Occam Fusion! Now with sqrt(-1) fewer blades!
When is it going to be bad to understand computers when you work with them?
What a dumb discussion. What a bunch of pussies.
The real problem is that the guys who are using the heavy duty numerics aren't the same guys who can write in assembly or even have much understanding of machine architecture. /n
We manage ~2 million lines of fortran code for computation. I compile with various modes of optimization often to get hanging compilers and hanging IPA processes for even moderately aggressive optimization.
To give you an idea of how much computation our machines are asked to do, a single pass can require 400,000,000,000,000 double precision multiplications.
So put that in your pipe and smoke it.
The point of learning assembly is not that everthing should be coded in assembly. Learning assembly will give people skills that they often would not have otherwise.
The efficiency of people who have learned assembly is not just thinking about the machine inetnals and pure execution speed. It also the skills they have learned to handle complexity. If you write anything of decent complexity in assembly, you damn well better learn how to write clean code, otherwise, along with all the other details you now have to keep in mind, it will bite you in the ass. You learn to structure data appropriately, or you waste time (programmer effort) now handling memory at a much lower level than with a higher level language. You learn to modualarize, or have painfully long (source-code wise) obscure code that really isn't fun to debug. And you also learn to comment (or you get damn good at reading code).
If I'm writing a program in Perl in 10 minutes that is executed in 10 seconds....
.1x as slow as C, in which case I'd have to execute the program 6600 times to break even.
But I can write the same program in C in 20 minutes and it takes only 1 second to execute...
I would have to execute the program 66 times to break even. If perl was 10x as slow as C, which isn't true. More realistically, perl is
*IF* you assume computational time is equal to human time. I cost $60/hr, or $10 per 10 minutes. A $1k computer, appreciated over a year, costs $0.02 per 10 minutes. At those rates, I'd have to execute the program 3300000 times to break even.
Even on a computer that cost $1 million, the program would have to be executed 3,300 times to break even.
Perl is better than C, for the vast majority of cases programs are written for.
paintball
Of course this is after thinking about the design for awhile. Rarely have I just gone and said "Ok I'm going to code this function now." without thinking "Ok what will this break? What will I want to add in the future and will it mean redoing this a different way?" I spend alot more time thinking about how to get the best flexibility out of a design than actually coding. I tend to think up the data structures first, by figuring out what data I need and what I'm going to do with it. Once I have that, I construct objects around the structures and figure out what methods I need to manipulate them. Everything revolves around the data, not the process. I try to keep the objects segregated on a "need to know" basis so that it's easier to swap out one implementation for another later. I don't want to be sitting forever rewriting the entire project because I've found that quicksort sucks for this data and I'm better off with a heap than a linked list.
When I actually get around to coding, my first concern is clarity. If I can't read my code, I'm going to be screwed when I have to debug it tomorrow, and totally lost when I need to add a feature or rework something next month. I tend to name my variables and functions for what they are, sometimes with fairly long names. Sure it's a pain in the ass to type cosine_offset and I can typo it alot, but it's a hell of alot easier than figuring out that w stands for cosine offset a month from now. Compilers catch name typos, they won't tell you what the hell you were thinking when you wrote the code. I find the stupid "hungarian warts" where you get names like pfstrqlrdwFOO are absolutely worthless. The only prefixer I use is p, for pointer, because pointer screwups are bad and it's possible to forget something is a pointer and requires different operands. I can usually figure out if something's an int or float or string pretty easy by following the names and what functions it comes from/goes to. GetInputString(myinput) makes it pretty obvious what myinput is, I don't need pcstrz in front of it.
Having other people able to read your code is a huge bonus. Readability = less time debugging = more time to improve or optimize later. I don't know ASM, but if my code is readable by someone who does, it's alot easier to get them to help me if they don't have to spend a week going "WTF is this variable for? What is the point of this function?"
Another thing I do that was taught to me by a very realisticly-oriented CS professor is go for low linecount. Outside of clarity, linecount is king. Why? Because fewer lines are easier to comprehend, tend to have fewer bugs, can be easier to optimize (into ASM for example). Functions over 50 lines are rare for me. My functions do exactly one thing that they're named for, I don't group an entire 9 step procedure into a single long function. If I have to do that then it'll be a function calling a bunch of other functions in order. That way when I have a bottleneck, I can just rewrite 25 lines of code instead of poring over 250 looking for where the slow code is and misunderstanding parts of it.
Granted I'm not the best programmer. I'm probably not even an average programmer around here given my lack of experience. I had a basic course in ASM at college that mostly covered MIPS, and an EE course that covered up through basic CPUs and registers. I know some of the concepts but have never written in ASM. Maybe when I finish the main parts of my current project I'll learn x86 ASM so I can optimize it.
Introducing the new Occam Fusion! Now with sqrt(-1) fewer blades!
So my advice is, don't learn assembly language. Learn Lisp or another abstract language. Think in terms of functions and algorithms, not registers and page faults. Learn to program minimally.
You need BOTH ways, the minimalist one goes for beauty and clarity (pleases the human reader), but the other is the realistic one and if you forget about it, you loose the game, after all is the register and page faults world that gets the work done, so I think its better to know both and choose whatever you want in any situation. :)
But you are right, as the distance between the machine and the language increases, so it does the dificulty of learnning how to optimize the code.
I've been waitting for a change in computer structure for years, where are those prolog machines, or java cpu's? lost in the bottom of logical computation ocean?
What's in a sig?
What's in a sig?
- Never Copy - if not necessary (be careful with the "=" operator in C++ and other high-level Lang.)
- Aggregate Information as soon as possible
- Preserve Locality
- Save Memory always - your Computer has lots of RAM, but little Cache.
- Be careful with 2D-Arrays and similar structures and consider the cache organiziation
- Try to use Regular automata wherever appropriate instead of more complex structures.
Some more important non-algorithmic ideas?I wonder how you whining Slashdot Linux wannabes would react if you knew that Randy actually said this in class one day in the late 90s:
"Windows is infinitely superior to Linux."
as there are already some 400 posts, perhaps noone's going to read this. Still, here's my two cents.
;)
Randall states that CS students don't learn assembly language anymore, or that if they do, they aren't being taught well. I have to disagree.
In our CS curriculum (Universiteit Leiden, NL) we had courses that learned us
(1) how to design a CPU, including ALU, load/store architecture and microinstructions for a fake CPU that interprets (a subset of) the MIPS instruction set. (digital systems design)
(2) write a compiler from a subset of pascal to MIPS code. The end result had to be tested on SGI Indy's. Present students still have to do this, but need SPIM, since the Indy's have gone, how sad.
(compiler construction *)
My point is that our curriculum is arguably representative of the standard CS bachelor, at least in Europe, and that learning everything from high-level languages up to micro-instructions greatly surpasses dabbling with programming in assembly.
I do agree with his main point though: you should know these things. My feeling is that more people are already acquinted with Randall's dark art than he thinks.
(*) offtopic: this course was the major stumbling point of half of all CS students. Some handed in the assignments 4 years late, after their final MSc paper.
It appears that either you are good at the math side and suck at coding or it is the other way around. I did fairly well here, but I won't go into my math
I'll give you real hard numbers.
I look after pnm2ppa, which is a print processor to convert pnm image bitmaps from Ghostscript to PPA, which are HP's worst ever printers. Ever. They are so dumb, they make Bush look like a Mensa candidate.
When I first came to the code, it was written by someone who thought they knew better than the compiler, and structured the code accordingly.
We had hand-unrolled loops, unusual and rampant use of the "register" keyword, the occasional volatile, and strange padding in structures to try to align the data to what he thought the processor would use. There were arithmetic "if"'s, nasty pointer usage, throwing away type information (ie casting to void *), and strange methods of going through the data.
When I hand simplified all the code, it went about 15% faster. In inner loop case, over 100% faster by re-rolling a single inner loop because the person who unrolled it didn't understand how branch prediction worked and even less about large data structure walking and L1/L2 cache interaction. gcc 3.3 improved the performance of the code by about another 15%.
But you know what made the biggest change? A simple replacement of floating point gamma correction with a lookup table ordered in the simplest possible way. That shaved literally 30+ seconds off every page render on my PIII/800.
And you know what? The new GLUT is shorter and more readble, and is easier to tune for color correct output. It costs about 4 MB of RAM.
Assembly has no place in the modern day programmer's skillset. Humans do not know how to schedule instructions properly. They do not know how branch prediction will work unless the data they use is static. They should not waste their time on understanding the difference in L1 cache strategies (which are wildy different in the x86 families and AMD Opterons). They cannot work out how to best keep the data pipeline full on a wide range of processors. But you can help compilers work this out for you by:
* Design the system in the correct way first time - what do you actually need to do? Don't do anything else
* Learn and keep up with the best generic algorithms for a wide range of activities (such as sorting, arrays, dictionaries, etc) and keep a library of well tested and bug free examples
* Write simple, clear, maintable code
* Never, ever, ever throw away type information
* Never, ever, ever throw away data aliasing
* Never, ever, use the "register" keyword
* Never use "volatile" unless you know why you need it
* Document tests, data and code properly. This pays off big time every time you come to add new features or fix old ones
Lastly, program like a software engineer not a cowboy. Code must be correct then fast. Not fast and wrong.
Andrew van der Stock
A computer is nothing more than a very fast player piano, and nothing less.
Simple, huh? But it is understanding this that is key. First off, how a player piano works: there is a reel of paper, the "roll", upon which is impressed, via a series of holes, one for each key, and a few for pedals - the notes which will be played. It is pulled past a row of vacuum air valves by a clockwork or electric motor. This same motor drives the pumps for the air system, when a hole passes, the note is played - how long the hole is determines how long the note is held down for. Other holes determine how long the pedals are held for. The roll of paper unrolls at a constant rate. I believe there were "operator" knobs to set this rate for various rolls, as instructed on the rolls.
And that is how one of the Victorian-era programmable machines worked. This is all a computer really is. This is how a CPU works.
Imagine the roll of paper with its holes, each "row" on the roll being one "address" in this very long (but finite) amount of "memory". At each address, or "row" of holes, is encoded an "instruction", consisting of a bit pattern, that is read by the "CPU" (the valve system), which "executes" the command to the rest of the "system" (keys and pedals). Then on to the next "row"...
This is how a CPU works, and it is how assembly works. The CPU has a bunch of address space, and it is mapped to the addresses to which the memory can be instructed to read or write. The clock on the system causes the CPU to advance states in the system, which increments an address counter, typically called the "instruction pointer" or IP. This pointer is set to a value indicating the starting address of the code. When the CPU is told to "run" the code, the instruction pointer is advanced one address at a time by the clock. At each point, the CPU reads the data at that address. Let's say each opcode in assembly for our fictional CPU is one byte in length. Some of these opcodes say that the next byte might be data, or the next two bytes are data, or no bytes are data (the next byte is another opcode). Each of these codes causes the CPU to read the instruction, switch logic gates via electricity in the electronics so that a logic path changes to read the next bytes as needed and assign them to whereever (other memory, a register, a pointer). Some of these opcodes may be jump (JMP) instructions, in which the next byte or so represents an address to which to set the instruction pointer (thus, unconditional branching). Other opcodes may indicate conditional branching, in which the processing the CPU does for such an opcode reads certain flags, memory areas, or registers, and then jumps (or not jump) to the specified address based on the boolean outcome of the comparison.
You should now be able to see how stringing a series of opcodes (bytes) and data (more bytes) together, with the CPU stepping through it, electronically and electrically reconfiguring itself to shuffle data (which is represented by electrical logic states, like +5V=1, 0V=0, in electronic circuits - it goes deep, very deep). Name the opcodes according to what they do, and how many bytes afterward are "arguments", and there is how a CPU works, at the basic level. Just like a player piano.
All the CPU is doing is slogging through a whole mess of bytes and interpreting them to electronically re-arrange itself to perform calculations. There are further refinements of this - my explanation of how a CPU and assembler works is only a very basic one (I can't write a book for ya, can I?). One such refinement (and incrediblely, none other than Charles Babbage implemented a form of it in his plans for the Analytical Engine) is the concept of "microcode". Microcode is essentially assembler for which the CPU is pr
Reason is the Path to God - Anon
Assembly is for fags! Try brainfuck if youre out for a challenge *evil laughter*
Infinite time means everything that can happen, will. You being you is absolutely incidental. You do not exist.
An earlier poster mentioned how such a skill can help you find compiler bugs. This can be the case, but it is rare; I have located two such bugs in 20 years of programming. A more common use is to locate bugs in your code. When your brain refuses to see the missing braces around the wrongly indented code, or an spurious semicolon at the end of an if or while statement, reading the generated assembly code can save some extra hours of frustration. You will be able to see that the code the compiler generates differs from the code you think you wrote, and this will point you to the bug's location.
As I argue in Code Reading, other cases where reading assembly code can be of use are:
To read compiler-generated assembly code you need:
Obligatory "hello, world" program written in i386 assembly:
Diomidis Spinellis - #include "/dev/tty"
In an article I read the CEO of FSecure was quoted as saying the biggest recruitment problem is the lack of assembly language teaching in universities these days.
I guess it helps if you are in the business of making bugs, too.
I'm sorry if I haven't offended anyone
"Now, granted, you shouldn't use an O(n) algorithm when an O(lg n) one exists to solve the same problem. However, knowing the difference between O(n) and O(lg n) has nothing to do with knowing assembly. The only benefits you can get out of knowing assembly are constant-multiplier speed increases. And, frankly, shaving off 50% of 0.1% CPU time used is not going to help much."
While I agree with much of what you are saying, you're 100% wrong here. Try as much as you want to, the engineers who wrote the optimizer for the compiler know far more about how to make its output efficient than you do. Most attempts to "hand-optimize" code actually make it worse. The only place you need to use assembly is when writing certain low-level parts of an Operating System or a Device Driver. Do you know which of the 15 different ways to zero a register executes the fastest on your CPU version? How about which one is the smallest instruction? Your compiler does. Also, it knows how to schedule the operation so that on the latest 5 CPUs, the execution happens in parallel with the previous set of instruction. Which variables should be in registers, and which should be left on the stack? Heap? Did you play the red-pebble, blue-pebble game? How does the scheduling improve if we unroll that loop? Can we improve the branch-prediction here? These questions are answered by the compiler to degrees you don't need to or want to know about. Are you optimizing for space or time? Do you understand why optimizing for space may improve the execution of your code more than optimizing for time?
Your algorithm assertion about an O(n) vs O(lg n) only holds as n becomes very large, and is only relevant if the situation warrants it. It isn't bad design to choose an inferior algorithm which makes the code more maintainable. Your O(n) time algorithm may run within O(n) space that has been allocated locally and happens to be within the cache, whereas your O(lg n) time algorithm may run within O(x(n)) space already allocated, but outside the cached memory. Now your O(lg n) includes O(x) page switches at a painful C.
The point is that knowledge of algorithms doesn't make you a good engineer. Engineering is about designing something, building it, and testing it.
Assembly language is terribly important to understand when writing C and C++, because you learn the constraints of the system. You cannot dereference a NULL pointer and expect your program to behave correctly. If you don't allocate enough memory for your input, and you don't document it, and you don't check your assumptions then you deserve what happens to you when a customer exploits you by asking for x bytes and delivering x + exploit bytes.
Granted, you do not need to completely understand all assembly language to get these concepts, but I wouldn't hire you as a developer on my team if you couldn't tell me what an Access Violation is, or why it happens when you dereference 0, I also think it's important that you understand interrupts and exceptions, and how to write code so that if an exception is thrown, you handle it correctly. Being sloppy because you are lazy or uninformed isn't acceptable when millions of people run your code. Just because your specific computer runs at 3GHz with the ability to retire instructions from separate threads simultaneously doesn't mean that your customer's battery-saving laptop running between 300 and 900MHz makes short work of it while they're running their MP3s and typing out their homework. If you need to spin up their HD to hit virtual memory because you're being lazy, you may have just cost them 10 minutes of battery life. Spinning up and spinning down a HD is expensive.
"Really, the speed of modern CPU's is sickening. I can't count the number of times I've written a piece of code, thought "This is going to be so slow...", then watched it execute near instantaneously. Even when running programs in a prototype programming language I'm working on -- which currently runs about 40x slower than C, because it's a c
Holy shit, I know you. ^_^
FC Closer
Totally agreeing with Mr. Jones on this.
I, as well, went to UC Riverside, and studied under Hyde in two courses. CS-013, lower division course, but still tough, because it covered many many aspects of ASM which helped me understand in basic terms what the direct consequences of typing code can lead to.
Very great teacher, and I'm glad I had him at UCR. Btw, Art of Assembly is a great book!
Only 15 params? Way back about 94 when I was working at MS supporting Visual C++ I took a call from some plank who was moaning that he was getting an internal compiler error.
:)
Looked it up. The compiler was failing as there was a limit of *100* parameters. So I told him and started getting all wound up. I asked how many he was trying to pass. it was something like 120 odd. (i turned the mic off and laughed hehehe)
He asked when it would be fixed. I suggested that as this was the first call ever on this topic it would not be a high priority.
Customer goes mad and starts saying things like 'how am I supposed to get my work done now?'. I gently suggest that he could put the parameters in a struct and pass that across.
Customer went dead quiet, thanked me and quickly hung up
BTW if you want to know what torture is, trying having to explain how to use - extern "C" - about 3 times a day for 2 years.
Please help an ignorant me.
25 years ago when I learnt assembler on a PDP11, it was assembler. These days, it is assembly.
Can someone enlighten me on this change ?
Thanks !
Here at Adelaide Uni, Australia, where I'm currently in 2nd year Computer Systems Engineering, everyone who does CS or any of the Electrical Engineering degrees do a semester of DLX assembly... and I'm pretty sure there's more to come in later years.
It's not an optical illusion, it just looks like one!
... viruses used to live in the boot sector of a 5" floppy disk, while keeping the whole bootloader there as well, AND in the worst cases there were a handful of those on a single disk (bootsector) ;-) I can understand the fun of writing something like this back then, but the "Hey, dude, click here for your document..." is just plain silly... ;-)
Paul B.
Understanding how a computer works is more important than learning to write in assembly language. In fact, assembly code has simpler constructs than most high level languages. The perceived complexity of assembly language is due to the tedium of programming solutions to even simple problems.
A good start then is to learn how a computer works by reading "Code" by Charles Petzold or "Computer Organisation & Design : The Hardware and Software interface" by Hennesey and Patterson. With such an understanding you will know "when" to write in assembly instead of high level language. When you ought to write code in assembly, grab an instruction set reference manual for your architecture and/or a tutorial on how to interface C/C++ functions with assembly and you are off.
Assembly language is surely on the way out. It becomes irrelevant in distributed, cluster or grid computing. How will you optimise if your cluster is made of heterogenous processors ? A variant of the problem has already cropped up with modern processors supporiting different kinds of SIMD instructions leading to messy template switched code. Optimisation then shifts strongly towards choosing efficient algorithms rather than fidding with assembly. In any case, code generation should be the headache of the compiler where its better solved than each application trying to do it on its own.
Assembly is for amateurs! Reel programmers program in AppleScript!
Who moved my sig?
Randall is the author of Write Great Code (from No Starch Press).
He should learn asseembly in order to get smaller binary code.
Yeah, i agree, ultraedit is a fuckin great editor.
Good for programming, hex editing, text editing.
Great all around...very powerful.
It's easier to fight for one's principles than to live up to them.
1) Lex & yacc are fucking shit.
2) Java is not a scripting language. Get over it.
Sorry to reply to my own post here...
:)
But infact, I just found a 350mb divx, right clicked..ultraedit..
Took about 8-9 seconds(raid0 helps), but ultraedit opened it just fine...I'm now looking at all the hex and ascii, std hex editor.
Give it a shot
It's easier to fight for one's principles than to live up to them.
Naturally it's helpful to use libraries in C. However, the 'libraries' I speak of in Perl are actually built-in language features that don't natively exist in C. If you read the post I was replying to, you'll see that the poster was talking about *re-implementing* all of this in C. Naturally it wouldn't have to be re-implemented in Perl, because it's already a part of Perl. And if you used external libraries that you didn't write yourself in C, then you'd have to make sure they were (a) equivalent to Perl's built-in language features, and (b) faster.
:)
All things being equal, any equivalent program written in C is highly likely to be far longer, more complex, and more difficult to write than the same in Perl--that's because Perl does a ton of things for you, many of which I have already outlined. Of course, if you don't need these features in the first place, it might make sense to write it in C. But given an arbitrary Perl program and then being tasked to write an 'equivalent' program in C... well, it's just going to end up being way more complex. If that Perl program uses eval, you might just have to write an entire Perl interpreter.
Of course this entire line of argument has been ridiculous from the start--Perl and C work together just fine, so you can always use Perl for the rapid development, and C for speed, as needed. In fact, there are tons of Perl modules that just consist of a Perl API to a bunch of C functions, usually for speed, or just to use an existing C API in Perl.
I know what you mean about being I/O bound--I do a lot of PHP programming. Now, PHP can be an embarassingly slow language sometimes, but that doesn't matter when you're busy waiting on a network connection to a database!
pb Reply or e-mail; don't vaguely moderate.
I thought the reason one learns assembly language today is to be able to write compilers.
Sindri Traustason.
Hm,
... that bothers me.
... and here he says, well its anyway better to just make a factor two or three improvement? See now here:
... He thinks making a program 2 or 3 times as fast makes the difference of successfull or not. But the same approach by using hardware he finds inappropriated.
... thats not a big difference. Great software on those low performing machines where most of the time games. And the games clearly where written in different perspective. No one said: I want it looking like this: make it so. Programmers and game designers where more or less the same persons, so they could write good code yielding good games by experimenting. How if we make thagraphics like this? How does it look and feel? How if do it like this? Remember Doom? Doom was great because the coders found a simplified way of 3D scene generation (raycasting). Thats an algorithm. Thats data. Thats an idea on how to transmorgrify specifications into a program where the product manager does not see that his spec was transformed. Because it looked like he expected.
seems that article is a try to hype the book: "Write Great Code". While some few small trues are in the articel msot of its conclusions are false conclusions
Some random quotes:
It's all well and good to say, "I'll just find a better algorithm!" However, finding and deploying that algorithm, if one actually exists, is another matter.
A programmer able to find a better algorithm is also able to deploy it. Why does the author think different there?
say, going from an algorithm with O(n^2) performance to one with O(n lg n) performance, but the truth is that most of the time a constant factor of two or three times improvement, applied throughout a piece of software, can make the difference between a practical application and one that is simply too slow to comfortably use.
Hm, isn't that a little contradicting to the authors rant? He argues that the programmers are so poor, they can not even find more efficient algorithms
Advances in computer architecture have exacerbated this problem--for example, you might hear a programmer say, "If this program needs to be a little faster, just wait a year or so and CPUs will be twice as fast; there's no need to worry about it." And this attitude, probably more than any other, is why software performance doesn't keep pace with CPU performance.
Ooops: he clearly does not know what programming is about
Well: but this is the most clear statement that teh author has really no clue how two write efficient software on old hardware:
Programmers were doing great things with software back in the days when their applications were running on eight-bit 5MHz 8088 PCs; the same techniques they used to squeeze every last bit of performance out of those low-end CPUs provides the key to high-performance applications today. So, how did they achieve reasonable performance on such low-end processors? The answer is not a secret--they understood how the underlying hardware operated and they wrote their code accordingly. That same knowledge, of the underlying hardware, is the key to writing efficient software today.
Assembly language or C
Most good programs used two principles:
a) lookup tables, e.g for sinus values
b) looking at the requirements from a different perspective, which seemed to behave from the outside like expected, but was achieved in a unconventionel way
Long after that the geeks started to look at the underlying hardware. Before a) and b) did not happen it makes no sense to check wether LD A, #$00 is faster or EXOR A, A.
Underlying hardware is the point where you have to fiddel far mroe than just knowing assembler. How do you access a Joystick? Today with DirectX or some other device driver. In my days you wrote to a memory locations. That caused a condensator to be loaded. Then you started to read a second memory location in a loop. The
Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
So, once again everyone is coming out of the woodwork to explain why this article is either right or wrong based entirely on the tiny subset of programming tasks that they actually do.
For some applications - embedded systems, drivers, games (my specialty), or any other real-time application - assembly is either very important to understand or actually essential. There is (or was) no other way to program the PS2's vector units, for instance.
For database work, batch or text processing, network admin, or anything else where speed is nice but not a show-stopper, "make it work" is much more important than "make it work fast."
I've always felt knowledge of assembly makes one a better programmer regardless of the application. Even on a high level, understanding why (unnecessarily) using data types larger than the system's register size is going to hurt performance can only be a good thing. Understanding assembly is fairly fundamental to understanding computers, as opposed to just using them.
sig fault
Maybe learning assembly will be usefull to the programmers of those companies that make very expencive engineering packages sold for 5000+ USD, and they can be downloaded free on the wares sites in a matter of few days after release.
I do disagree on several points that have been raised, but they don't defeat the final conclusion:
- I do agree that premature optimization has been lethal to many software projects. But I have met as many people who commit PO in HLL's as assembler, so this is not an argument for or against the language.
- The comparisons of startup times and code sizes with the '80s (the 80's! Why, in the 70's we had only... never mind) are amusing, but uninformative; there are a lot more services embedded in the average OS or word processor today. There is a degree of bloat, but the statistics are misleading.
- Hand-crafted assembly code is unlikely to be optimal in light of processor pipelining, multiple execution units, and scheduling. I used to know how many clock cycles each instruction in the PDP-11 instruction set would take to execute for each addressing mode; this information is not nearly so useful for today's processors.
- There are architectural considerations beyond assembly. As early as 1983 a colleague of mine brought a VAX-11/780 (a screamer for its day) to its knees, and came to me complaining bitterly about the processor and/or compiler performance. It turned out that the code in question, which used massive multi-dimensional arrays (in FORTRAN), had compiled into a two-instruction loop (three-operand multiply and an increment/branch), but the code was generating six page faults per iteration! He would not have avoided the problem just by using assembler, but my deeper understanding of the machine led to the identification of the problem.
All that being said, the title of the article is "Why Learning Assembly Language is Still Good." At the end of the day, while I opt to write in Java (or Objective-C, which I'm just picking up), I am better equipped to write good code knowing assembler, and a few other things behind the language and runtime I'm using.
Speaking about Perl and Assembly, it is important to mention that there are modern object-oriented assembly languages with asynchronous I/O, events, threads, multiple inheritance, garbage collection, built-in Unicode support, etc. See: Parrot Assembly, and IMCC:
"IMC stands for Intermediate Code; IMCC stands for Intermediate Code Compiler. You will also see the term PIR which is for Parrot Intermediate Representation and means the same as IMC, but for some each Parrot developer has his favorite term. PIR was the original term, where IMC seems to be the vernacular. It is an intermediate language that compiles either directly to Parrot Byte code, or translates to Parrot Assembly language. It is the preferred target language for compilers for the Parrot Virtual Machine. PIR is halfway between a High Level Language (HLL) and Parrot Assembly (PASM)."
How Is IMCC different than Parrot Assembly language?"PASM is an assembly language, raw and low-level. PASM does exactly what you say, and each PASM instruction represents a single VM opcode. Assembly language can be tough to debug, simply due to the amount of instructions that a high-level compiler generates for a given construct. Assembly language typically has no concept of basic blocks, namespaces, variable tracking, etc. You must track your register usage and take care of saving/restoring values in cases where you run out of registers. This is called spilling.
"IMC is medium level and a bit more friendly to write or debug. IMCC also has a builtin register allocator and spiller. IMC has the concept of a "subroutine" unit, complete with local variables and high-level sub call syntax. IMCC also allows unlimited symbolic registers. It will take care of assigning the appropriate register to your variables and will usually find the most efficient mapping so as to use as few registers as possible for a given piece of code. If you use more registers than are currently available, IMCC will generate instructions to save/restore (spill) the registers for you. This is a significant piece of every compiler.
"While it is possible to write more efficient code by hand directly in PASM, it is rare. IMC is still very close to PASM as far as granularity. It is also common for IMCC to generate instructions that use less registers than handwritten PASM. This is good for cache performance."
For a good introduction to Parrot, read Parrot: Some Assembly Required by Simon Cozens. There is a great article (also on ONLamp.com) Building a Parrot Compiler by Dan Sugalski (I have no idea why it wasn't posted on the Slashdot front page).
(By the way, for those who read off-line, here is a printable version of the linked Why Learning Assembly Language Is Still a Good Idea article in one piece.)
Sincerely,
Pan Tarhei Hosé, PhD.
"Homo sum et cogito ergo odi profanum vulgus et libido."
A number of years ago, while I was working for a Baby Bell, we were building a system, and integrating it with BEA's Tuxedo. One day a couple of the consultants came to me, to tell me that it was crashing, and they couldn't figure out why.
I pulled it up in the debugger (a Sun box), and stepped through the code...and, when I found it was crashing in Tuxedo, I did something the consultants (young guys) had no clue you could do...I stepi'd *into* the binary.
Now, I didn't know Sun assembly language, but that was irrelevant. I nexti'd and stepi'd my way through, and found the name of the function it was crashing in, which will *always* be there, even in a stripped binary, and where it was doing it in the function.
I could then call BEA (I was senior technical, and Rank Hath Its Privileges), and get info from their developers.
Turned out to be the environment, not a bug, but the point is, once in a while, *knowing* what how things work Down There will save your butt, and maybe even lead you to better code.
mark "and I pushed my kids to know what
happens under the hood of the car, too"
Superficially, that seems an obvious truth, but it doesn't necessarily hold in practice for several reasons:
In other words, with today's compiler technology, and more importantly today's run-time environments, C is no longer automatically the king of performance, and it is both theoretically and practically possible for much higher level languages to outperform even hand-optimised compiled C code.
Of course, the price you pay is the initial overhead for the JIT compilation process, usually when a program first loads. However, this is one area where rapidly increasing hardware speeds really tells, because that directly reduces the overhead of that bootstrapping process, so the field of more level the faster hardware gets.
I expect traditional, compile-only technologies to fade into the background over time; in the programming language "performance vs. safety+power" spectrum, they aim at a target nobody will need to hit any more. There will always be a need for LLLs, if only to write the underlying platforms to support HLLs, but for regular application development, their days are numbered.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I have seen to many people wasting their time reordering code and coming up with obscure ways of doing an if statement that might use a few less cpu cycles.
But I still think inorder to program efficant code you still must know assembly. The best courses I took were about compliers. This lets you know exactly how the compiler will optimize that assembly you know, so you know what is worth optimizing in a high level language.
For example, a lot of the things people do like rearanging local variable instanciation has absolutly nothing to do with how the machine code is actually written. The first think a compiler does is translate your code into a meta-code that has the exact same syntax style everywhere. All the variable declarations are moved to the front, every for, while, and do-while is turned into a while. All the code is normalized into a functional equivalent.
Then the code is optimized, if statements may be turned into the logical opposite, extra variables will be eliminated, code will be rearranged to increase parallel processing.
If you write code with this in mind you focus more on the important problems, like is this loop n-squared or just n.
But in-order to know what to optimize in code you still need to know assembly.
-nicnak
For those who don't know Parrot, I forgot to mention that Parrot is a VM which will serve as a backend for such languages as Perl5, Perl6, Python, Ruby, Tcl, et al. IMCC is an intermediate language which will be a target of those high-level languages' compilers and Parrot itself will serve as a portable interpreter of compiled byte-code, with JIT support on many platforms.
Sincerely,
Pan Tarhei Hosé, PhD.
"Homo sum et cogito ergo odi profanum vulgus et libido."
The skills I developed as a teenager in hand coding self modifying code written in 6502 assembly and writing DOS programs straight in microsofts debug still come in useful every day, even though the 6502 has long been defunct, and the Pentium 4 has ver little to do with the 8086 I learned to master. Oh my youth was spent so productively.
It impresses the girls more than anything else, I tell you!
Being a programmer and not knowing at least the basics of assembly language is like being a doctor and not knowing what a cell is. Depending on your specialty, you can get by all right about 99% of the time, but if you hit a problem that stumps you, you won't be able to delve deeper into it because you won't know how. A deeper knowledge gives you insights, because where the rubber hits the road, it's all bits turning on and off in registers. If you don't understand what those bits are doing then it might as well be magic and it's time to break out the prayer beads.
The Moore-Murphy Law: The number of things that will go wrong will double every 2 years.
In theory, a really good assembler programmer could produce more highly optimized code, but not on a consistent basis and within schedule constraints.
I don't argue that assembler isn't useful. I learmed more about how computers work wwhen I took an 8080 assembler class in college. And for certain problem domains like embedded systems, assembler is often necessary. But I don't write any more code in assembler than absolutely necessary.
The majority of 3D optimisations is deciding what not to draw. Quadmaps, octrees, BSPs and so forth, are all techniques for quickly discounting large areas of polygons. The bottleneck of most 3D games is the drawing of the display. You may, perhaps get 1% or 2% improvement using assembly, but I doubt it. Today, compilers can optimise code pretty well. There's little difference in raw speed between C and assembly.
In addition, games don't just compete on framerate. Games have to be very, very, very stable. If a word processor crashes, people seem to be able to live with it. If a game crashes just as you were about to rack up a new hiscore, then the player is going to be very cross indeed. The more assembly is used, the more unstable the game is likely to become.
Thirdly, there's the difficulty of time. Assembly would obviously take more time, for benefits that are pretty much negilible. Coding inner loops in assembly really wouldn't improve framerate by any great degree, and would just contribute to the overall expense and instability of the system.
There's no problem knowing assembly. In many cases, understanding how computers work is very useful. But coding in assembly on modern PCs/consoles, even for video games, isn't likely to have very good results.
3D optimisation is all about having good algorithms. Case in point; I designed a 3D, OpenGL demo in C++. I then designed a similar demo in python. The one in python ran much faster, partly because I knew what I got wrong on the C++ demonstration, but mainly because in python, I could code better optimisations (various frustrum culling and octrees were the main ones), in a much shorter space of time.
In C++/SDL I had to write algorithms for taking a bitmap and converting it into an array, and then creating a heightmap. In python/pygame, image loading was done for me, and creating a heightmap was quite simple. The rest of the time I used designing an octree interface for my terrain.
Lots of musicians make their own instruments. Examples:
"Andrea Neumann has custom made her own instrument, the innenklavier (inside-piano)..."
"I heard a guy playing on the street the other day and this guy was so funky; he was a very cool musician. He made his own instrument and it was so interesting."
"He [Steve Roach] studied these traditional techniques and made his own instrument with aboriginal didgeridoo master David Hudson."
"Most taiko groups in North America still make their own drums ..."
"They make their own drums from what must be 50 acres of their own forest land, and they replenish the forest by replanting more trees." (Due To Javascript, click on Airto's Stories and then With The Kodo Drummers)
"Aboriginal people still make their own drums to this day, and spend a lot of time forming each one perfectly."
Enjoy,
-- Jamie
To this day, the lessons he taught me remain indispensable. For those who haven't taken a course from him, I suggest at least reading his writing pertinent to the development of skills as a programmer. Do not, however, take any lessons from him on the art of social graces.
I still think that the best course he ever taught was the one-shot CS 185, or commercial software development. There, we learned what it means to plan a project and be off by a country mile on how long it would take. Better there than in the real world.
Randy was quite the stickler on commenting code. I think that, more than anything else, is a testament to his vision of churning out disciplined programmers, even if it meant they hated his guts. I am only too sorry he didn't figure out how to interact with others like a well-adjusted adult, or maybe he would have kept his job at UC Riverside. In addition to being a student, I had the distinct displeasure to regularly interact with him on his Mirage+ research program (Distributed Shared Memory).
I wonder what he would have said about Java. Mr. Jones, you are right, he definitely made a great weeder course out of x86 Assembly. I was on a very short list of Art students to take the course. For me, the weeding worked the opposite direction. Six months after I took CS 13, I came back as a Computer Science student. I've met CS grads with master's degrees from a dozen supposedly more reputable who know less about operating systems, or programming in general than the average 2nd year CS student at UC Riverside. That is to say, someone who has passed CS 13!
Treasure your experience with Randy Hyde, good or bad you learned from it.
Randall Hyde regularly said that in his Assembly Language courses. Be aware that there are still occasions when Assembly is all you get, like embedded systems.
One time long ago I wrote a compiler for a simple little programming language which generated code for the 6502. It was the most useful personal project I ever did, even if the results weren't exactly brilliant. (the language was quite limited and the code not really optimised at all.)
I think this would make a good project for CS undergrads. They'd see just what the code they've written in a high-level language is doing at the metal and get a new appreciation for why, for example, it is bad to pass fifteen large parameters by value.
I guess in the US most universities actually do have a compilers class. Here in the UK, none of the universities attended by me or my friends offer anything like this. The closest my university came was some really trivial assembly programming on a PIC microprocessor to make some red LEDs blink on and off.
I was reading hex dumps and hand coding small assembler routines in high school (read: 24 years ago), and its been an invaluable skill over the years. I've written 'C' programs that call assembly routines to access OS functions that no routines existed for, understood how parameters got passed on the stack so when something got corrupted I could look at a hex dump and figure it out within minutes.
I took the TCP/IP software for an old minicomputer at my old job, licensed to the particular CPU, and figured out how to defeat the licensing so it'll run on any machine... all with no source, just by decoding/hacking the assembler and changing a few BNZ (branch Not Zero) to straight branches. I've played with building my own boards, and writing drivers for them.
From the standpoint of knowing how things work.. having the base knowledge of how the underlying hardware works, I can pretty much pick up any language on the fly.
I had a guy recently who I had to explain why:
status="green";
if (result1 >= 0) status="red";
if (result2 >= 0) status="red";
was better than:
if ((result1 >=0) && (result2 == 0)) status="red";
else if ((result1 == 0) && (result2 >= 0)) status="red";
else if ((result1 >= 0) && (result2 >= 0)) status="red";
else status="green";
no concept of the difference in 6 compares & 3 logical and's, vs two compares. Not that his way wouldn't work.. but *efficiency*. In a lot of ways, in my mind, mastery of assembly language can bring great insight into the *best* way to accomplish something.
That's true. The author's point was that you should be aware of the cost. I don't see a conflict.
Friends don't help friends install M$ junk.
But I'd turn the premise around - I think that the best programmers learn how to code at the lowest because they want to and are interested in it. Then they learn about both the benefits and complications (pipeline stalls, cache effects...).
But on another level, teaching assembler in college is increasingly difficult. Students in many CS programs are hard pressed to learn much more than Java and C# - very few know any language other than those in the C/C++/Java/C# family plus Perl and Python. Instead they learn all about GUI's, IDE's, .NET and so on.
I'd love to see students really learn assembly language (though ideally it would be for something other than the plug-ugly x86 series architectures), but then I'd also love to see them learn Lisp, Haskell and a few more languages, as well as Unix, Windows, VMS and a few more OS's, as well as HTML, XML, TeX and a few more ways to mark up information, as well as OpenGL, Postscript, X windows library calls and a few more graphics systems, as well as Calculus, Linear Algebra and a bit more math, as well as.... (well, you get the idea).
I am in an industry-leading company. There is no reason to use assembly.
Here's what I do for a living:
* XML
* Database
* Multi-threading
* Web-site design
* Real-time processing
* Data mapping
* Minor calculations
* Web services (straight XML or SOAP)
Assembly isn't worth anything in this environment. I also expect that the bulk of developers are very similar. Remember that the bulk of business code used to be written in COBOL? That's the type of software I'm talking about. We happen to be a J2EE shop, so we're working in Java. Our code is deployed to multiple architectures (x86/W2K, x86/Linux, SunOS, AIX).
I would be interested to hear how knowing assembly helps you with advanced algorithms and data structures. It seems to me that a higher-level language will help a lot more! Not to mention good OO design and component-based architectures.
Now, a bit of back-tracking. I'm not saying that assembly is worthless. There will be areas that it makes sense - but I really doubt that the majority of software developers have any use for those skills. Most developers are not:
* Writing low-level device drivers (graphic, network, etc)
* OS Kernel hackers
* Microcoders (I expect this to be the largest congingent in the list)
Face the facts, most developers must concentrate on a business problem at hand and efficiency at the chip level isn't a concern. In general, if you're worried about the computer's efficiency you better check your algorithm and/or design - there is probably one with a better fit!
In 14+ years of professional development, I haven't had to worry about assembly. In 20+ years of software development, the only place I worried about assembly language was on the trusty Apple IIe, my ONE class in assembly (not sure it helped), and now my hobbies with microcontrollers. That's it!
However, I think the only times assembly is really needed is (in a few cases, C++ will do the job almost as well):
- Cracking - Obvious reasons, you'll need to know how to program in ASM to know whats going on in programs, and therefore how to 'crack' them.
- Kernel/Other core file development - Again, pretty obvious. Apart from the fact you can't really write kernels in VB and whatnot, you will want these files to be as fast as possible.
- Graphic-Intensive games - Again, you want the game to run as fast as possible, you'll maybe get 60 fps if written in ASM, compared to about 10fps if written in VB.
- Virus writing - polymorphic viruses, for example, if you want the program to actually change its contents when a virus scanner checks it, writing it in VB or something will quite a bit more than challenging.
There are probably other cases too.I think it IS important to know how computers work - as in the CPU, registers, etc. But in most cases, it's simply not needed.
If you want to optimize, you can learn how to optimize code in your own language. For example, 2 * 2 * 2 will be about extremely faster than 2^3. StrComp() type functions are faster than If (UCase(string1) = UCase(string2)), etc.
Emacs will eat a 100MB file and ask for more. :-)
Seriously, just yesterday I was editing a 80MB debug logfile in emacs. Loaded in a few seconds; once it was in operations were just as fast as normal, including macros/etc. This was on an 800MHz PIII.
I completely disagree with Hyde about the importance of efficiency. Sure, I'd like apps to be smaller and faster. But 99% of the time, what I want to be improved in apps I use are:
* Usability
* Security
* Learnability
As a developer, I also rarely care about efficiency. I'd much rather developers spent more time making their code:
* Readable
* Maintainable
* Debuggable
I also agree with other comments that even if you think efficiency is important, assembly by itself does not help very much in understand what's efficient. That's because so many other factors besides the lines of code impact how your program runs, such as:
* Compiler and runtime environment (e.g., JVM)
* OS implementation (e.g., scheduler, virtual memory management)
* CPU architecture (e.g., pipeline, cache, superscalar execution)
Would knowing assembly be better than not knowing it? Sure. But considering all the things that it would benefit a programmer to know, how important is assembly? For the vast majority of applications out there, I think assembly is not nearly as important as many other things.
This is the first -1 post in this story! Waht a greats achivments for mee. HAHA. Linux losers fukof. hahahahahazzzzz.
Well I just checked my alma matter, Lehigh, to see whats :
required there these days. They appear to have merged a lot
of the CS program with the CSE dept., probably a good thing.
But even the BA program requires two classes requiring assembly. Even Lafayette College, the nearby arts and crafts school has courses that delve into assembly. So,
being the totally un-PC person that I am, is the 'they don't teach assembly anymore'
a) urban legend
b) dependent on the 'quality' of school you attend?'
When the FFT came out, a lot of effort went into cutting down the number of arithmetic operations -- eliminating "trivial" operations like multiply by 1, multiply by 0 and add, as well as they higher radix butterflies (radix 4, 8, 16). The simple radix 2 FFT given in many DSP texts was offered as a "teaching example", but "production" FFT programs were complex masses of FORTRAN code that attempted to identify all the optimizations.
In my own experience, the simple radix 2 FFT is best for the modern x86 where as you say x86 is just an API to a RISC core. The minute you start putting in the optimizations, you need additional loops, branches, and tests, which trip up the pipeline. Arithmetic ops are fast compared to extra loops, branches, and tests, so the old mainframe FFT subroutines were optimizing the wrong thin.
bleh that's bs everyone knows al gore likes movies about gladiators
As you are working with Java, x86 assembly may not be the most insteresting thing to learn for you.
However, I'm convinced that understanding JVM byte code and the garbage collector is required:
- knowing how the garbage collector works helps to avoid memory leaks
- exmaining the byte code of your own program will help you to learn how the compiler works. For example, how it uses StringBuffer for String concatenations.
Are all stupid.
Forth is your master!
BOW before the god of Forth you weak mortals!
In CompE school we took intro programming courses and datastructures freshmen year, followed by a full year of Assembly/Machine Programming the following year. I thought this was a pretty good approach; define the basic abstractions of what you'll be doing, and then go learn exactly how they work. (and then moving on to silicon programming and digital design, progressing even further from there, you *really* get to understand how those little C programs work)
The curriculum should certainly include assembler, but only because learning assembly is a way to gain better insight. I've written my fair share of ASM code over the years, but today it's good for supporting higher level languages, and pretty much nothing else.
Consider the effort to get optimisations right by hand on modern architectures when compilers are written to do it systematically, the lack of anything beyond the most primitive functionality compared to HLLs or archives like CPAN, and the complete lack of portability in an era where shifting your code on diverse platforms is becoming ever more important. All of these things are good enough reasons to opt for a higher level alternative in their own right, and all are near universal truths in today's development environments.
That's not to say ASM isn't useful for the right things. It's just that those things are such a vanishingly small part of the software development world that I think ASM's value is now far greater as an aid to understanding higher level languages than it is as a development tool in its own right. If you need to write ASM code, sure, take a specialist course, but don't waste time with the details in a general programming or CS course; there are far more important concepts to teach in a limited amount of time.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
For more on the joys of Assembly programming, you should go see Gibson Research.
Sometimes programmers can be a little smug in assuming that every other programmer is working in the same environment that they are and therefore they take their hard-earned wisdom from their particular niche and evangelize it to everyone else. Sometimes that evangelism borders on a geek-version of adolescent bullying as we try to put-down or shame everyone else for not doing things just as we do.
The profession of programming has broadened to the point where it is IMPOSSIBLE to advocate a one-size-fits-all mantra to all programmers.
Computers have become so ubiquitous and the things they do so broad that the profession itself has splintered into many different subcategories each with their own INDIVIDUAL best practices.
So I think anyone trying to advocate a way of doing things should always qualify it by specifying the environment that they think suits it best.
The way someone writing code for a PIC is going to approach it differently from a device driver who is going to approach it very differently from a web programmer writing C# code to deliver web pages or a game programmer doing real-time graphics or someone writing an embedded app who is concerned about battery life or a missile guidance system or medical instrument who is concerned about stability.
That's not to say that there aren't any universal best practices, but everything is a cost-benefit assessment. There are cases where the time investment in the optimization will not payoff with a measurable increase in efficiency that actually helps the bottom line to any degree. Ultimately the best programmers are those who are able to satisfy BUSINESS needs, not just thier own perfectionism.
This is true of just about any form of creation. Someone building a cookie-cutter apartment building approaches it differently from the replacement World Trade Center or a tent or a treehouse. Take artwork. A comic strip artist is not going to lavish the same amount of detail on his daily strip that went into the Sistine Chapel. The work that goes into creating a Hyundai is different from what goes into a Bentley or a Hummer or a tractor or a motorcycle.
Always customize your approach to the niche you're in.
Personally I think the curriculum for coding should begin with asm, and the student should work his way up to the higher level languages.. c, pascal, and finally java or perl.
I really think learning asm makes the most sense when using it on a cpu you've built from scratch. Though I think building a software simulation will do, as all the time spent debugging the hardware isn't really a skill a CS major needs anymore...
I agree, I get really confused sometimes when writing TI C67x code. But if you know how to take advantage of the delays slots and the parallell units you can do amazing thing. For some functions it is not to hard to cut the cycle count into half, and if you think about it for a while you can cut it into half again. For me it can take days to translate a few lines of C code into to optimized assembler, but it pays of if it makes your algorithm run in real time.
I can see you have much to learn about assembly.
Doesn't it make you feel good to know that our freedoms are protected by politicans, lawyers and journalists.
I took CS13 taught by Randall Hyde back in my Freshman year (Spring 1998 Quarter). It is one of my favorite courses that I ever took in my 4 years at UCR. Randall Hyde got trashed by a lot of the students, but I respected him. I thought his teaching was effective and sound.
Not sure what happened to him after he stopped lecturing at UCR.
He still has his website/webserver up: http://webster.cs.ucr.edu
Did any of you guys participate in the 'computer shoot' he used to have every quarter or so? I guess he stopped holding them before I started college, but I remember he had a webpage about it on his site (no longer on the site).
What I generally do is overwrite new to place a 64 bytes marker before and after the memory block, which is then checked during delete, and will exit with a stack dump (and a hex dump of the block) if corrupted.
At exit I dump all blocks not deleted (to catch leaks), and I litter my code with asserts (which also do stack dumps) plus have a printf-kind of system, where the level of output can be toggled (often at run-time, if the application i am working on has a user interface (I have a debug-menu component which I just link on my application)).
Due to all the run-time checks, I generally catch mistakes the minute I make them -- I have debugged/resourced lots of other programs and have also programmed in assembler, so it's not a skill I lack, but I honestly never have a need to debug my own programs (except when the compiler produce the wrong instructions, but this is mainly just looking at the assembler output, rather than using the debugger).
My memory system doesn't watch for stack-corruption. This however never really happens, because I only place objects on the stack or const arrays -- if I need a mutable array I use std::vector
I also define _GLIBCXX_DEBUG, which turns on all sorts of sanity checks in the standard library.
A buddy of mine and I are working on a board game to help teach machine coding concepts. My friend is not a programmer, but he says just the little bit we've done on the game so far has greatly improved his understanding of how computers really work internally.
My motivation is that the next generation of computer programmers (people growing up now and eventually my 6-year-old son and his contemporaries) should have only had exposure to OOPsy languages, GUI-screwy windowing environments and so forth, and won't have a clue about the many, many layers of abstraction that lie between those and the hardware.
I see this as a potential major crisis in the making for the programming community in general.
"Anybody can change the world, but most people probably shouldn't." -- Marge Simpson
For systems where the users can compile and execute their own programs, the users must have some level of trust, where any responsible admin would know their identity, etc. . On public access systems, for example, no compiling or usage of uploaded binaries is allowed (or shouldn't be, for any competent admin) Sure this is a big deal, but it won't cause as many problems as say, the sasser worm for Windows, or any remote exploit.
IT CAN BE FUN!!!!!!!!
It is also true that knowing more programming paradigms makes you a better progammer in all ways. My personal experience is that I am a better C/C++ coder becasue I know both assembly and LISP, as I am a better LISP coder becasue I know C/C++, and so on.
Being a better coder dosn't just mean writing faster code or more readable code. It means being able to write code in a style that matches the requirments of the project. Knowing how to go fast or clean or flexable or some combination is where the real skill lies.
I look back fondly on my the time I spent assembly language programming on the Cray. It has been of great use when I have to write fast image processing code in C. Enjoying the work can be a big part of doing a good job.
I have struggled with programming concepts for years. One day I happened upon The Art of Assembly by Randall Hyde. Up to this point I had spent countless hundress of dollars on various teach yourself books, even some texts that were used to train programmers at one time ( the Knuth series ). Yet the basic concepts of programming eluded me. I knew how to declare variables etc ... yet I couldnt grasp how to design my program. Enter AoA, of all things this free text opened the door and all the texts I had read previously clicked. Everything seemed to fall into place. After a year I am still learning to program, but have since begun on different languages and platforms. I sent Mr. Hyde an email thanking him. I was surprised when he replied. Needless to say his text had inspired me to learn ASM. Though with modern compilers it isn't necessary to know ASM, I have found it useful.
I am Bennett Haselton! I am Bennett Haselton!
I don't buy either of these premises:
1) That assembly has major relevance today
2) The best implementations are written by those who've mastered assembly language
On point #2, "best" is very subjective and subject to interpretation. Does this mean, minimum # of defects per X lines of code? Extensibility?
As someone who learned assembly in the early 80's (when I got started on 8 bit microcomputers) I don't see much relevance for intimately assembly language today.
It would be like me arguing that I should learn the power industry since one day I might need to build my own generators to run equipment.
At some point we have to resist the urge to think we can "know it all" and simply stand on the shoulders of others.
While learning assembly is fun, after 10+ years of being a software professional, it would be nice if people know f*cking high level languages. Back in '99 when I was with an Internet company and we were interviewing for "software engineers" I was amazed at how many people claimed they knew C and could not write a f*cking strcpy routine. I didn't care about the prototype (ANSI or not) I just want to see code that did this:
while (*dest++ = *src++);
Sure that's the super compact one line version with no C prototype but the prototype is NOT what I was interested in, e.g., "What's the ANSI C prototype for strcpy?" I simply wanted to see if a person knew C... and if you do not know basic pointers, you don't know C.
As it turned out, not one person I asked this question answered it. In fact, an amazing number of people made no attempt at it. I guess the Internet boom created lots of a people who saw dollar signs and were applying for jobs way out of their league.
That's C mind you. When you look at the fact that C++ was crazily popular I can add to my anecdotes. I used to inteview people on C++ and I often asked people to rate their C++ skills. I gave them a scale and qualified 7 through 10. Mind you the scale was arbitrary but the point was to clue people in as to what my expectation of a 7 might be. One of the points I would make about a 7 (out of 10) is "You should be able to tell me off the top of your head why you would want to write a copy constructor." An amazing number of people would rate themselves 7 or higher. Want to take a stab at what the first question I asked was? Yes, "When would you want to write a copy constructor?" And like strcpy in C, most "C++ developers" seemed to be clueless on just that one question.
Thinking in assembly language is not something that happens overnight but once you do you definitely have an understanding that few people have. Problem is, the applicability of this skillset for most "developers" is incredibly niche. Unless you're writing a compiler, debugger, writing firmware directed at embedded systems or reverse engineering some piece of code (regardless of the source media), assembly is pretty much irrelevant given the rich number of abstractions the software development community has created.
Some of it you can attribute to open source some of it is purely Moore's Law (computing doubles every 18 months). Today we don't think twice about having a virtual machine on top of our "real computer" running our code but back in the 80's, forget it, the IBM PC was running at a mere 4.77 MHz and the performance of Pascal code compiled with Borland's Turbo Pascal completely blew away performance coming from byte code Pascal compilers employing the University of California San Diego's P-Code system.
If you've entered computing in just the last ten years it's hard to appreciate all this but back then it made all the difference in the world.
However, today we are not obsessed with CPU performance since performance gains coming from CPU speed increases have become minor with respect to the applications most people use, e.g., Intel has decided to stop using "GHz" to rate its processors. Besides, anyone who understands computer architecture clearly knew it was Intel's way of
Indeed. Many people will agree that learning assembler is beneficial, but the reasoning given is spurious.
The guy who drives the mechanical excavator keeps a spade in the cab. Why? Not because it will make him more efficient at driving the machine, but because just occasionally he might have to "debug" a buried pipe or cable, or get into the corners.
In addition, rolling his sleeves up and shovelling some mud will give him a better intuitive relationship with the stuff he works with.
You have to know how to do any job by hand before you are truly proficient at the mechanised version.
I'm glad I learned some assembler, but I'm also glad that most of the time there are tools which will do it better than I could.