Is assembly language programming taught just for the sake of history ?
Do compilers generate better assembly code than the one written by a novice programmer?
DEFINE better -> from the point of the execution time of the assembly program
Is assembly language programming taught just for the sake of history ?
Do compilers generate better assembly code than the one written by a novice programmer?
DEFINE better -> from the point of the execution time of the assembly program
Paraphrasing wildly, quis compilet ipsos compilatores?
(No, not valid Latin. Which is useful in a similar way to assembly, though much less).
Better than Novice programmers? Possibly. Almost certainly.
But Assembly still has it's place, for example in Operating System Development, in Device Drivers and embedded hardware, and in algorithms (i.e. games and scientific stuff). Sure, Novice Programmers may not write good assembly code at first, but that applies to every language.
Assembly (and even "higher languages" like C and C++) rapidly lose their importance in normal Business and Web Applications, but there are areas where they are simply not replaceable (yet?).
Do compilers generate better assembly code than the one written by a novice programmer?
Yes. Almost always. (Unless you're one hell of a novice) In general a human will write code that is meant to be read easily, one that highlights the logic. Compilers will tend to write code that accomplishes the given task as minimally as possible, at the expense of readability if needed. This almost always produces "better" results.
Yes to the first, no to the second. An expert programmer will be able to write more optimal assembly than a compiler.
However, these days hand written assembly is generally relegated to performance critical sections (think 3d-engines in games) or low power hardware (embedded systems).
Do compilers generate better assembly code than the one written by a novice programmer ?
Yes.
Is assembly language programming taught just for the sake of history ?
I'd guess it's taught so that you understand what instructions are seen and executed by the CPU, and understand what a compiler is doing.
DEFINE better -> from the point of the execution time of the assembly program
"Better" meaning:
Novice programmers don't write assembly. :-)
I've seen assembly used for
the first steps in booting the computer
wrappers for interrupts
low-level locking
other similar stuff in the OS where specific machine instructions are needed
extremely optimized code
code for extremely small machines
code for machines where no compiler exists
Everything else is best left to compilers, for ease of programming and portability.
Given the number of Microsoft security updates out there that are specifically targeted at known attacks that manipulate buffer overflows, I'd say that there is still a thriving assembler savvy community out there ;) I used to do much of my programming in assembly back in the days of 8 bit, and it certainly taught me how to program efficiently. Is it a necessary skill for most programmers? Probably not. Is it a desirable skill for those who really want to understand how computers work? Absolutely.
Depends on the compiler, actually. Considering the complexity of today's processors, optimization at assembly level is pretty mechanical stuff which is done best by compilers rather than humans. In fact, there are cases that this is not true. Specially in using SIMD instructions for pretty specialized tasks, embedded development on ARM processors (implementation of JPEG for a digital camera, for example), the code can usually be optimized further by humans. Even in those cases, people usually write the code, compile it, and then optimize the compiler-generated code by hand.
This does not, however, make assembly language a worthless thing. There are other cases you want to write in assembly.
Depends. There are a lot of things that the compiler will always be better at. It's far better at figuring out register allocations, for example. It's also typically better at keeping track of the cost of different instructions, and how to hide instruction latencies. And if you get these things wrong, you'll completely destroy the performance of your program. Further, novices probably aren't too aware of latency hiding and such, so no, a novice would probably write terribly slow assembly.
There are also things a human being can sometimes do better, sometimes algorithmic tricks that are not obvious from looking at the input source code, sometimes choosing what code to inline, or which branch of an if statement is going to be called most often.
But in the general case, the compiler will probably write better assembly code than most programmers, and especially better than novices.
So why do we teach assembly? I can think of several reasons.
I think compilers are generating better code than novice programmers.
Taught where?
In mechatronics and related programs, assembly is still required to program some embedded devices. Even if the device has a good compiler, assembly knowledge (i.e. knowing the opcodes of the chip and the memory map) is necessary to create quality, efficient, usable code.
Cheers,
-Richard
One of the reasons we teach assembly to novice programmers is so that they will no longer be novice programmers, that is to help them gain insight to the low level functioning of the machine.
There are already some good answers here about why we teach assembly language. But I want to answer:
Do compilers generate better assembly code than the one written by a novice programmer?
Absolutely yes. But it goes further: compilers beat experienced programmers, too, since most experienced programmers are pretty rusty in the assembly department (I am!).
And even further: compilers hold their own vs. expert assembly language programmers. Some of today's CPUs allow for complex optimizations that require lots of calculations to take full advantage of. The Itanic is a good example of a a CPU that expected compilers to work hard (but failed, oops).
Of course, it also matters what code you're trying to compile.
Some code constructs are intended to do something simple, but are confusing to compilers (e.g. I know that file X will almost always be on disk, so I can optimize in favor of the code path where it exists; the compiler has to handle both cases in a balanced matter). Other constructs, especially those which express intent over mechanism can give compilers an opportunity to produce code that is well-tailored to the context (e.g. the .NET JIT compiler will know whether I have 1 or 64 CPUs at runtime, and PLinq queries let the compiler do its thing). It is very difficult for a human to generate the assembly quickly enough, between the time a user launches a program and when they expect to see the splash screen!
I would teach assembly in every curriculum because any computer scientist or programmer should know how the chip works at a very low level. Registers, L2 cache, vector units, branching, pipelining... these are all things a programmer even working in a high level language like Ruby should be aware of.
I think schools teach assembly language for the benefit of those who want to pursue a career in lower level programming (OS, drivers, etc.). Somehow, I ended up with a career doing as an application developer doing C# and never used any of the assembly language that I learned in my lower division course. Was a rough go for me too, especially at 08:00 AM...
It's not that long since I worked on mainframes where assembly was used extensively for the visual interfaces.
I have no idea why, but I suspect they are still using it.
I wondered the same thing. Looking back I think it has helped with my ability to abstract a problem down to it's smallest details and back up again.
A good optimizing compiler will surpass not only novices but human experts.
A modern, multi-core CPU with instruction pipelining and other sophisticated features can require substantial "bookkeeping" for optimal code generation. There's no shame in admitting that software can be written to outperform humans as the number of factors to be juggled continues to increase.
It is useful for a well-rounded programmer to have at least an overview-level understanding of all levels of the software "stack", but the field of programming has become so complex that few programmers can (or need to) be masters at all levels. I believe that every programmer would benefit from a basic understanding of machine code, but also believe that the typical application programmer can have a very productive career without ever diving down to the bare metal, not to mention having to keep up with the constant advances in CPU design.
Knowing even a tiny amount of ASM - even ASM for a theoretical instruction set - really helps to understand what all those compiler options do.
I don't see much point in being an expert in assembly language except in a few niches but I believe that it pays to know at least the gist of the lower level stuff even if you never deal with it directly, due to the law of leaky abstractions. If you ever need to write fast code, it pays to know how abstractions are implemented. Also, understanding how stuff works at a low level provides intuition about what is possible at a higher level. For example, assume that a novice programmer knows nothing about memory management and just assumes that through "magic" memory gets recycled when it's no longer needed. Without understanding that garbage collection works by tracing and not semantic code analysis, it would be impossible for this programmer to understand the importance of getting rid of references to unneeded data even in a GC language.
My department requires assembly-language programming because we believe it is an important path to understanding how the machine works. We think this level of understanding is sufficiently important that we require it of all students, even though maybe one student in a hundred will have anything to do with the back end of a compiler.
Because the legacy 64-bit x86 instruction set is pure hell for everyone involved, we have de-emphasized writing assembly code and put more emphasis on reading and understanding assembly code. We think analysis of assembly code is an important skill for C programmers and C++ programmers, who may occasionally have to diagnose a fault by looking at the content of registers and single-stepping through machine instructions.
Compilers do a better job than almost anybody with ordinary code and especially with making good use of registers. When it comes to making effective use of the vector unit (e.g., vector SSE instructions), compilers are not so good, and people who want guaranteed vector performance or who are dealing with audio or video codecs often have to resort to small chunks of assembly code in performance-critical inner loops.
For what it's worth, I think that having even a vague understanding of what happens at a lower level enriches a programmer, and is an essential part of a computer science education.
I think I know why they do it. Once while in class, been thought assembly, scratching my head, trying to figure out where I went wrong, or what bad deed did I do that brought me to this class, I noticed a green on my professors face.
It was his way to get back at us.
In other words, I don't think that it really, does any good to any one to study assembly. If you have to work with it, you can learn it in a week, and if you don't well, just be happy, that you don't.
Assembly is taught because knowing assembly means that you understand how the bare metal of the machine works. (At least approximately, given the added complexity of constructs like microcode, pipelining, instruction scheduling, out-of-order execution, hyperthreading, branch prediction & speculative execution, etc, etc... but you can't really understand these without having a fair grasp of assembly to begin with.) The specific instruction set that you learn is not so important (indeed, x86 is often considered undesirable and poorly designed; I learned MIPS assembly/architecture), because what you're really learning is the fine detail of how a typical stored-program machine uses different storage locations and logic operations to convert a bunch of bits into a meaningful calculation.
If you want to be an average code monkey, then knowledge of assembly is probably unnecessary. You can write perfectly fine javascript, perl, and sql without having more than the faintest clue what is actually happening on the CPU chip. But if you want to be a great programmer, you will need that deeper understanding in order to grasp why some language constructs perform better than others, or what you can do to reduce cache misses, or how buffer overruns destroy security and what you can do to prevent them, or invent some clever new thing that's currently impossible/difficult to do...
As an analogy, your average bus driver doesn't need to know a lot about how an internal combustion engine works in order to do his job. A formula one race car driver, on the other hand, needs a much better understanding of exactly what happens when she steps on the accelerator pedal in order to be able to judge precisely when (and how hard) to do so. Someone building a tiny remote-controlled (internal combustion) car also needs to know how an IC engine works, even if it will be using an off-the-shelf engine produced elsewhere. And even the bus driver, if he understands how the engine works, will be able to recognize engine problems better and be able to give better problem reports to the mechanics that will fix them.
When I took an assembly course as part of my programming course, it gave me a much deeper understanding when I returned to my regular programming language ('C' at the time).
If your main programming language is Java, .NET, PHP, Ruby, etc... it may be too much of a leap between your current language and Assembler to get the same insights as I got in 'C', but it will still give you insight into what is happening in the processor.
There is another good reason to teach assembly--debugging. If there is a problem in a call to a third party library sometimes the only way a developer even has to isolate a problem is to look at the assembly. Granted this does not require a deep knowledge of assembly language coding but at least a passing familiarity with assembly is helpful in that particular case.
Why is assembly taught?
Well, for one thing, you can't be a hacker without knowing it. Hackers must know the ins and outs of the system.
If you are just a hobbyist programmer, then sure, you don't have to learn it. Chances are you will continue to be a novice programmer forever ... , or something (pretend I'm saying something profound!)
Asm is part of the path to true understanding of computation & computers.
Compilers can hide features that the CPU has.
IIRC multiplying large integers in C can easily lead to overflow, but the MUL instruction in x86 actually writes the answer in EDX:EAX. You can actually get the correct results.
Also, as mentioned, vector instructions are often poorly handled. GCC does not utilize SSE other than to use it in place of x87 FPU.
It can help you understand why the first version of this array traversal is much faster than the second. Low level side effects can show up in high level code.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Diagnostics;
namespace array2d
{
class Program
{
static void Main(string[] args)
{
const int len = 10000;
const int width = 10000;
int i, j;
int[,] a = new int[len, width];
int[,] b = new int[len, width];
Stopwatch sw = new Stopwatch();
Console.WriteLine("One row at a time...");
// Traverse the array one row at a time
sw.Start();
for (i = 0; i < len; i++)
{
for (j = 0; j < width; j++)
{
a[i, j] = 1;
}
}
sw.Stop();
Console.WriteLine("Elapsed time {0}", sw.Elapsed);
Console.WriteLine("One column at a time...");
sw.Reset();
// Traverse the array one column at a time
sw.Start();
for (i = 0; i < len; i++)
{
for (j = 0; j < width; j++)
{
b[j, i] = 1;
}
}
sw.Stop();
Console.WriteLine("Elapsed time {0}", sw.Elapsed);
}
}
}
A brick layer does have to know how bricks are made, only how to set them mortar, but a master brick layer will know about the entire process including the raw materials from which brick and mortar are made.
A programmer does have to understand assembler, or digital logic, to write a program, but to try to master the art of programming we try to learn all we can. I grew up along with computers (any one out there remember the 4004 which proceeded the 8008). I've learned digital logic using discrete transistors, to IC,to CPU, to machine code, assembler, BASIC, FORTRAN, FORTH, C, C++, and now C# and JAVA.
Do I consider myself a master, no I don't, but I am not done learning yet.
Yes, in most cases a good compiler will generate better code than most assembly programmers. But, not in all cases. Highly optimizing compilers have lots of clever algorithms, but like all programs, they're dumb. So, once you move outside of the cases they were designed for, they don't optimize so well (e.g., SIMD stuff).
Also, compiler optimization can be fragile: just because the compiler can do an optimization doesn't mean it will do it in any particular situation. As a programmer in a portable language, you don't have direct control over what it does with your code, so you can end up doing all sorts of voodoo tweaks to your "portable" code in hopes of provoking one particular compiler to do the right thing...
Anyway, all of the above is mostly relevant to the inner loops of performance-critical code. Not every programmer fools with that kind of thing. And, true, after you take assembly course, you may not ever write a line of assembly for the rest of your life.
But, no: we don't just learn assembly for the sake of history. Every piece of code you write runs on a real machine. Even though thousands of people have written languages, compilers, virtual machines and operating systems to enable you to use the machine more conveniently, the strengths and weaknesses of that machine still determine what is easy and what is hard. And learning assembly is the largest and most fundamental part of understanding enough about the machine to make informed choices about how to program.
Even if there is zero chance of you ever writing assembly or a complier (which is the case for most of us), Understanging assembly language gives you a much clearer understanding of:
I want my doctor to understand microbiology, even if he's just prescribing a pill. There's nothing "historical" here: our understanding of low-level biological processes is better today than ever.
Physicians could set a broken bone just fine 500 years ago. What separates modern and ancient medicine men is largely their understanding of why things happen. I'll take a modern physician over an ancient one, even if he's not writing out SN2 reactions on his whiteboard.
hi my friends , i want to know why we need assembly and why we do not compile our program directly to machine languages, i mean high level language compile program to assembly then assembly convert it to machine language?