views:

2003

answers:

30

Many claim that, when performance is at a premium, it's sufficient to write and compile C code to get near-optimal code that is additionally quite portable. I don't see much of a assembly/assembler discussion on stackoverflow (about 0,3% of the questions right now are tagged any of those tags, many of which refer to .NET Assemblies).

However, perphaps there are still realms where this bottom-level approach still wins worthwhile profits. What do you think?

+2  A: 

Not for big applications, I think.

Device drivers may benefit from having part of the code coded in ASM. Embedded software is another place where ASM still plays a major role.

Sometimes you may want to optimize a function to its maximum because you call it over and over again so you may code it directly in assembler.

Frankly I don't see other good reasons to use it.

Now that I think about it, we were discussin about cracking just a couple of days ago. That is another area where ASM is key!

Remo.D
Are operating systems small applications?
Vinko Vrsalovic
No, but you don't write entire OS's in assembler. Certain parts, yes, but mostly it will be a higher level language.
Greg Whitfield
+2  A: 

Personally I believe in the majority of cases writing Assembly is complete overkill. However having said that a lot of gaming/embedded/OS code requires Assembly for performance gains, or purely because they need to use assembly (e.g. a bootloader). So it still is very much alive, but only in specialised circles. But then again, use the technology that suits, that is, if you are writing a notepad clone, or general desktop application you would be crazy to use Assembly.

mdec
+21  A: 

Sure there is. Just think of programming drivers or simply doing stuff on real-time embedded devices - or just using embedded stuff without real-time :)

I think upcomming FPGA circuits embedded in COTS hardware will bring up the need for low(est) level languages (asm, vhdl, verilog) to a new revival.

addition:

The knowledge how assembler "works" makes you a better programmer! Since you understand what really happens behind your (high-level) code. Like:

  • what are function calls really like
  • what is memory (how is it allocated, freed, what memory leaks are)
  • how control flow (for, while ...) is done in hardware (goto, if ...)
  • how all the library stuff works (compiling and linking applications)
mana
I think you're over-reaching a bit in the better programmer section. Assembler will teach you nothing about memory allocation/leaks or library stuff.
Benoit
Knowing assembler may not mean you know *everything* to be a good programmer, but in general understanding assembler helps you understand how the machine works - the kind of stuff mana outlined.
Michael Burr
Learning assembly teaches you how a specific platform works. Which reminds me of a quote:“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%." -- Donald Knuth
R. Bemrose
Yep, but Donald Knuth would never defend with that the horrible code which you can see in these days. Ever seen a = b + c among Java Integers (not int)? That amounts to 3 boxing/unboxing conversions. Avoiding stuff like this in the first place is not premature optimization.
Blaisorblade
True. I like to put it this way: I've never met a really good programmer who wasn't proficient in assembler. Don't confuse correlation with causality though.
Thomas
Knowing all those things might lead you to the wrong conclusion that that's the only way to do function calls, control flow and linking. Calling in method in Java for example can be faster than jumping to a subroutine in assembler, because the JVM might actually inline the method code.
Joachim Sauer
agree with Joachim... Machines are becoming more and more diverse and soon we will all have hardware JVMs. Exceptions are slow on some language/arch combos, fast on others, function calls may or may not be auto inlined, or the constantly called functions may be cached in the instruction cache, etc. You don't need to know assembly to know what a memory leak is. I don't see how knowing how flow control is implemented at the hardware level will make you a better programmer. It's common sense to know function calls have overhead because of the callstack.
Longpoke
+15  A: 

For general computing, I don't think that assembly language has much traction. Compilers these days can actually generate more efficient code than a human in general.

However, if you are in a small critical loop that will be executed millions of time, you might gain some performance advantage by doing it in assembly.

The other case where assembly is absolutely needed is when you are doing bare metal programming on an embedded system. Some of those chips might only be programmable in assembler. Also, even for a 32-bit processor with gobs of memory, the bootstrap code executed when you power on the system will be in assembler, as there is no C-stack setup yet, and there are processor registers to initialize.

Benoit
*ALL* chips are only programmable in assembler. If a chip exists that doesn't have support from a compiled language then someone will come and write a compiler for it.
tloach
The amount of bootstrap code that has to be in assembler is tiny with most processors. Linux has quite a lot of assembler in the boot loader for x86 but that's because it's all real mode code, it's almost all C after it switches to protected mode.
Mark Baker
Most embedded systems support some sort of high level langauge too these days, but yeah, assembly is still used for them a lot.Regarding gaining performance for some small amounts of hand optimised code, I'd say only if you _really_ understand the processor you are working on.
Dan
+7  A: 

Inline assembler can be helpful in certain places when you need to do low-level stuff, not necessarily to get more performance but for example reading CPUID or things like that. If you know the code, you get what you want in 3-5 lines of ASM instead of using and including API calls - if they are available at all.

I see ASM used most often to use the best possible way to cast float to int, or other data types, simply to use a CPU's native instructions where available. This is probably the single most important use of ASM nowadays, making use of a CPU's special feature where available and necessary (especially console/embedded programming).

steffenj
+1  A: 

Besides high-performance and embedded computing, the other important use of assembly language is in writing compilers.

You want your code to run on silicon? Somebody has to generate the machine instructions :)

benjismith
Someone needs to read the Dragon book...
fuzzbone
I guess he meant the "code generation" back end of compilers.
Remo.D
once the first compiler run, the others could use it to build themselves. at the third generation, assembly is no more required - on a theoretical point of view.
Lorenzo Boccaccia
+4  A: 

If you're working on optimising real-time or high performance applications (such as video games), it's very handy to be able to read assembler, even if you don't write any. Most of the time it's fine to trust the compiler, but if you've got an inner loop that's a bottleneck, it can be worth double checking.

These days, in application programming, if you need to work close to the metal (for example, writing your own high performance maths library or lock-free data structures) you'll probably be mostly using intrinsics rather than writing assembler. But to do this effectively, it's good to have an understanding what's happening under the hood.

To get to a good reading understanding of assembler, check out Berkeley's course notes on MIPS. IBM has some good info on PowerPC too.

Matt Curtis
+1  A: 

Yes, I think there is.

Every times there is no HAL between your code and a piece of hardware that you need to talk to, it's almost sure that you have to waste a lot of time fighting with the compiler. That's the time when assembly comes handy.

In an "everyday" project it's IMHO almost useless.

Axeman
+4  A: 

Incidentally, here's one of my favorite resources for understanding the cost of various CPU instructions:

http://www.agner.org/optimize/

I could probably count on one hand the number of lines of assembly I've written since college, but I go back to those Agner guides again and again to understand performance issues on modern CPUs. (He gives the most helpful explanation of branch-prediction algorithms that I've ever read.)

benjismith
+19  A: 

Reverse engeneering, for any reason you might need it.

arul
I second this. I have worked on a project for a client where i needed to reverse engineer an old system written in C and inject new functionailty into it. Funny though, i learned how to do all that hacking diablo 2.
mattlant
Reading assembly is more useful than writing it here... I just debugged a C++ compilation issue which was the result of compiling a structure in two different source files with different define flags by looking at the disassembly and noting the offset used didn't match what GDB told me.
Ben Combee
A: 

We use assembly, but we're working on operating systems where it's mostly necessary.

In the vast majority of cases, the compiler writers will know more about the instruction set and how to optimize than you will so I'd leave it to them.

Pretty much all of the applications that ship with our OS (and quite a few bits of the OS itself) are written in higher-level languages.

paxdiablo
A: 

I can't believe noone has mentioned The Art of Computer Programming, where the examples are implemented in assembly language for a hypothetical CPU.

I guess what I'm saying is that while assembly is used rarely outside of the examples already mentioned, there's certainly a point to learning it for one architecture or another.

Hank
Yep, but that is a legacy from the early days when it was needed. The modern rewrite still uses assembly because Knuth is so familiar with it that thinks everybody should know it. Assembly has an educational value, but using it for complex algorithms is too much.
Blaisorblade
+58  A: 
DGentry
Well said! (would vote up, but I've run out for today)There seems to be a huge misconception that embedded programming and device drivers is all about writing assembler all the time. It's easily the exception rather than the rule.
Andrew Edgecombe
Some architectures can boot directly into C code. x86 is an example of the opposite though.
Thomas
"C" bootloaders are compiled into Machine Code... which is assembly. CPUs and MicroControllers are digital logic state machines. They need some form of OpCode system to define states and events for the system.
Matthew Whited
+1  A: 

I think being able to read assembly can still be very useful, particularly where you are debugging something that has crashed, or you are profiling a piece of C or C++ code for speed. I haven't had to count t-states for some years now, but it is nice to know that I still could. I actually miss programming in assembley, but thats probably a just minor personality defect ;)

I suspect that there are more people out there that know assembler than many would realise. Look at viruses that take advantage of security vulnerabilities by forcing the execution of a piece of code in an overflow buffer. For those writing antivirus software, I guess some assembley is still very much required. No amount of VB or C# is going to teach you how to solve that little problem.

Shane MacLaughlin
A: 

I recently needed to expose function exports from a DLL to JavaScript, with the argument types defined with embedded resources. This meant calling functions without the compiler (or me!) knowing the types or even number of arguments! The only dependable way to do this was using assembly to allocate the arguments on the stack and calling the function.

I also second being able to read assembly, I've found it a huge help, when the documentation for a library fails.

Simon Buchan
A: 

Although most software developers don't need to write or even read assembly in thier everyday job I think that anyone that is writing software would benefit from knowing assembly.

  • Assembly is the building blocks of our applications and as such it is impossible to really understand how program work without knowing assembly.
  • Assembly language is a powerful tool and knowing how to use it opens up job opportunities in many intersting fields.
Dror Helper
+6  A: 

Hardware Programming

Assembler is necessary when directly programming the hardware. Especially very highly embedded systems may lack a compiler. Even modern CPUs need a bit of assembler to get them bootstrapped, since in the earliest stages of the power-up cycle, there is no stack and parts of the CPU still need initialisation.

A area commonly associated with hardware and assembly programming, namely device drivers, are rather using CPU-independent kernel interfaces (Windows Driver Kit or Linux' internals).

Last, but not least, assembler can be used to quickly access a specific CPU-feature (CPUID, int/float conversion) without having to resort to a vendor's (possibly incomplete) API.

Understanding

Learning (any) assembler helps in understanding the behaviour of programs from low-level stuff like calling conventions and memory management to arcane topics like branch prediction. This understanding can be applied when reverse engineering, understanding what the compiler did, or optimizing the last percent from a hot spot (see below).

Thus knowing assembler is one of the necessary pieces to understand a computer from top to bottom.

Performance

Even large and modern applications have somewhere that one hotspot that can be significantly improved by the assembler mace. To cite a famous one, Microsoft Excel has its float formatting routine written in assembler (with tragic side effects).

On the other hand libraries have to perform at their best in any circumstance. Especially things like memset() can profit by hand-tuned implementations.

Code generation

Compilers need to generate assembler code. For this someone needs to know enough assembly to create the code generator.

David Schmitt
+1  A: 

Debugging in general and reverse engineering in particular. Some problems require debugging application binaries at the assembly level (memory management problems, dynamic method invocation, issues with exception handling, and many others). Sometimes when chasing down an application crash you may need to get into a debugger to understand what is going on. A basic understanding of assembly is fundamental for dealing with these issues. You'd be a very valuable team member if you are one of the few who can actually debug your way out of tough problems like these.

Max Caceres
A: 

Assembly may still be of use in specific circumstances, like:

  • size optimized demo-coding (4 kilobytes or less intros, see pouet.net or scene.org)
  • inner loop optimizations in 3d engines, sound engines (like softsynths, etc.)

For embedded devices programming, assembly may still be useful, even if nowadays there are C++ compilers for small chips, like Atmel, etc.

friol
+1  A: 

Timers are universally written in assembly. And there are very few people who can write them well.

Besides that bootstraps, embedded devices, and all the others that people have mentioned are good examples of occasions where, if assembly isn't necessary, it certainly has distinct advantages over higher-level languages.

cblades
A: 

I think a lot of proprietary hardware related software, embedded systems, and military applications use at least some assembly, they just have a lot less visibility compared to freely available Java programs.

You could theoretically make the same argument that C isn't really used because so much code is written in C++/Java/C#/Web-oriented languages, so if you look at the craiglist job postings you will see relatively few C jobs.

Uri
A: 

(C++ , C , Java... ) Higher level -------translate----------> Lower Level (ASM, machine code, micro code, IL ...)

As your knowledge of precisely how the translation from Higher to Lower is done , grows, the more you will find yourself substituting inefficient higher level code with lower level inlines (if possible)

E.g. knowing how loops are unrolled by the compiler, knowing how register allocations are done by the compiler/runtime, How different storage types affect memory performance, cache usage, etc etc.

If you don't know the 'translation' part or have no desire to learn it as it doesn't affect your particular usecase, then its of no real value to invest time learning asm.

But consider this: Your < high level code > crashed and all you may have is a crash dump that you need to analyze and fix the bug for some client/employer. What are you going to do?

Kapil Kapre
+1  A: 

It is worthwhile to have an know assembly even if you don't use it. I helps in understanding what is going on in your higher level languages. I was amazed when I was in college at how many Java programmers had NO understanding of memory layout, code generation or any type of physical hardware comprehension. When you first realize that code and data are all just bits - do you want to execute them, or look at them as data - that really blows some people away. It's always worthwhile to understand what going on under the hood.

Dan Hewett
+1  A: 

I agree with the general sentiment here. I think assembly is something very useful to know for various reasons, that said, most people should never need to use it.

  • If you're writing a web app, there is no reason you should need to write assembly. The same goes for general applications (say Quicken, etc).
  • Higher performance applications such as powerful games (i.e. Half-Life 2, Quake 4, etc... not Bejeweled), or computationally intensive work (i.e. some filters in Photoshop, some video editing/compression, etc) will use small bits, but the majority of the code is going to be in something higher level. I would even wager that many of those uses (not all, but many) may be avoidable if the compiler exposes some of the newer CPU instructions (SSE2/3, etc) that you are really trying to use (I think Intel's C compiler is supposed to do a good job with this) that normal code (i.e. a loop) won't just compile into.
  • If you are doing anything involving direct attach hardware (graphics cards, sound cards, etc) you very well could need it. Some hardware (like USB) you can get by without.
  • Embedded systems it's going to be commonly used (again, in small bits) to setup and access hardware, or on system (like some microcontrolers) where there is very little code space or you need to be operating at near max speed (you can't afford the inefficiencies of a cheap C compiler).

It's useful. It would let you do those situations above where it's called for. It gives you a much much better idea what's going on in the hardware and how programs and hardware communicate. That said, I think it's perfectly reasonable that someone could go most/all of their career these days and not need to know assembly (especially if you work in a CLR language like Java or whatever.Net).

MBCook
A: 

I use MASM32 for making debugging tools, convertors and everything small, that I can write in an hour or two. Low level coding is very easy when the code itself is compact.

Though it is not a matter of efficiency, just a personal habit.

akalenuk
A: 

My job is to validate the behavior of CPUs during their design. Most of my testing involves writing assembly tests to stress various aspects of the CPU.

Nathan Fellman
A: 

For general purpose programming I would say, assembler is useful only in cases when:

1) You know the platform you are writing software for very well. 2) You know capabilities of your compiler very well (including shortcomings/bugs).

2 is very important because compilers are very clever these days and they handle a lot of optimisations for you. If you don't know what you are doing you can actually end up writing assembly code which compiler can't optimise and end up having a less efficient solution than you would otherwise in a higher-level language, simply because a compiler would unwrap your code in assembly in a more efficient manner.

I experienced this sort of behaviour myself. I was learning SSE2 and tried implementing some vector operations using SSE2 instructions. Switching on SSE2 instruction set usage in Visual Studio project options and using only C++ yielded the same (if not better) performance.

However, like I said, if you require efficiency where you know for a fact that a compiler fails to generate efficient code, you can unwrap that yourself. How likely is it that you encounter such situation? Hard to say. My guess is, only by accident. If you profile your application and find a performance bottleneck you might stumble upon something like that and choose an optimisation accordingly (which might include coding in assembly).

Another reason you might want to use assembly for is code consistency. For example, you might be coding in a language which has X compilers which are used by large number of users. Each compiler interprets a certain code block in its own manner and as a result performance and stability varies. In this case you might want to consider using assembly (or a different more standardised language:)) to make sure your code is executed identically no matter what compiler is used.

sneg
A: 

The biggest gain in coding in assembler for most programmers (non-embedded etc.., you know what I mean) is when there is an assembler instruction to do exactly what you want, but the high-level language you use can't express that concept in a way that the compiler will understand that it should use that opcode.

Examples:

  • Some processors have built-in AES encryption functionality. How do you express that in C? (without it being added to the compiler)
  • get first bit set (without a loop)
Thomas
A: 

I code for MSX computers in Z80 assembler for fun. It is a machine with a relatively simple but complete architecture, that easily allows for programming 100% in assembler.

Konamiman
A: 

One very special reason to use assembler I didn't see mentioned here yet, is to have total control over the executed code. It is needed for smart cards to fight so called side channel attacks that allow to break crypto algorithms using statistical methods to find small dependencies between the processed data (depending on few key bits) and for example the current consumption. Small changes in code like changing the order of few commands (when the order does not matter functionally) can make the difference between a secure and totally insecure implementation.

Whoever