4 ms·
> Hardware access (not exposed by other languages), speed, and possibly executable size are the practical reasons one would write in assembly. This is a bit m
by bnegreve 12y ago
> Hardware access (not exposed by other languages), speed, and possibly executable size are the practical reasons one would write in assembly.
This is a bit misleading, accesses to physical memory, disks and to other devices are usually protected by the operating system, not by the language. So you don't have direct hardware access because you program in assembly, but because you run a program without the control of an operating system. This can be done in assembly, but also in C or in any other language that can generate native code.
The only thing that you can do with assembly and that you can't really do with higher level language like C is accessing processor specific registers/instruction sets (e.g. SSE). And this is typically done using inline assembly snippets, as there is no reason to write a whole program in assembly when you only need to optimize a single function.
So I would say that having better hardware access is not a good reason to write an entire program in assembly.
On the other hand, building small, standalone executable file that use very little (stack) memory is still relevant for programs that run on very small (usually embedded) hardware. Especially when they need to run fast or to have low energy consumption. So speed and memory usage are still pretty good reasons to use assembly :)
- dllthomas 12y agoHmm, I guess there is some room for misinterpretation. First, you seem to think I was answering a slightly different question - "In what circumstances should I make the decision to write assembly?" The question I was answering was closer to "When people need to write assembly, why?" The actual question, of course, was not quite either of those. Also, addressing a point of ambiguity: I did not mean "hardware access ([this is something that is] not exposed by other languages)" - that is, in general, wrong. I meant "hardware access ([when the particular thing is] not exposed by other languages)". This includes SSE (though that is starting to be included as builtins in some compilers). Outside of SSE, I grant that there isn't much on x86 platforms that is relevant to a game, since games on x86 platforms typically run under an OS. It can be relevant if you're writing a driver, though. And this can vary substantially by platform. And no, it's not a good reason to write an entire program in assembly unless a sufficient percentage of your program is calls to these things that the C inlines are just adding cruft. "On the other hand, building small, standalone executable file that use very little (stack) memory is still relevant for programs that run on very small (usually embedded) hardware. Especially when they need to run fast or to have low energy consumption. So speed and memory usage are still pretty good reasons to use assembly :)" No, that is substantially more misleading. Like I said, you cannot quickly do better than a modern compiler, and a compiler does it very, very quick.
- bnegreve 12y ago> I meant "hardware access ([when the particular thing is] not exposed by other languages ... Ok, I agree. >Like I said, you cannot quickly do better than a modern compiler, and a compiler does it very, very quick. I'm not sure what you mean by "quickly" but this submission proves that it can be done in reasonable time. And if you look at the code (for example here: https://github.com/icebreaker/floppybird/blob/master/src/game/bird.asm https://github.com/icebreaker/floppybird/blob/master/src/gam...), it's obvious that you cannot produce anything nearly as compact and efficient with a compiler. So, claiming that assembly is still a language of choice nowadays was maybe exaggerated, nevertheless it's nice to remember that no matter how good they are, compilers come with a cost. If you need some evidence simply compare the submitted code with any code produced with a compiler.
- dllthomas 12y ago"it's obvious that you cannot produce anything nearly as compact and efficient with a compiler." It's not obvious. We can argue over what's "nearly", but without even trying, manually converting the assembly to C I get 71 (1.5x) instructions out of gcc and that includes an inlining of animatebird. The resulting code is otherwise not so far from the original. It certainly reads more poorly, but that's to human eyes not x86. I'm not sure which would be more performant, and playing more carefully with the code and optimizations it can probably get even better.
- danelectro 12y agoWell, on Android the original Flappy Bird was 894kb in size, and this Floppy Bird is only 8.7kb. Plus the 8.7kb includes enough utility code to obviate the need to load an OS for the game to run on top of, so the size ratio actually is better than the apparent 100:1. The TAB key changes the bird's color scheme.
- dllthomas 12y ago"Well, on Android the original Flappy Bird was 894kb in size, and this Floppy Bird is only 8.7kb." You're actually making my point. Virtually the entirety of both those numbers is going to be image (and, on the Android version, audio data). Using lower-resolution assets is not something reserved to assembly language, and the size of the code is just not an issue next to that, most of the time. The biggest exceptions on desktops/servers being when executable makes the difference between spilling instruction cache and not. Things can get tighter on embedded, but there too tables and stuff are more often the cause of contention. "Plus the 8.7kb includes enough utility code to obviate the need to load an OS for the game to run on top of, so the size ratio actually is better than the apparent 100:1." Enough code to obviate the need for an OS (for this narrow use case, in Real Mode with BIOS calls available) is probably fewer bytes than enough metadata to convince Android to run you. But as mentioned, you're not actually comparing code size at all really. "The TAB key changes the bird's color scheme." I'm not sure what your point is here. Cycling palettes is a neat trick, but nothing new, nothing complicated, and certainly nothing that couldn't have been done as easily in another language. Edited to add: Perusing your other comments, you seem to have plenty more savvy than your comment would show... were you trolling or trying to make some oblique point that I missed or what?
- ANTSANTS 12y ago>The only thing that you can do with assembly and that you can't really do with higher level language like C is accessing processor specific registers/instruction sets (e.g. SSE). And this is typically done using inline assembly snippets, as there is no reason to write a whole program in assembly when you only need to optimize a single function. The other three most important things you can do in assembly that you can't do in C are: * Indirect jumps (aka the "labels as values" or "computed goto" extensions admitted available in GNU C) * Directly accessing status flags like the carry flag (necessary for efficiently implementing bignum arithmetic and CPU emulators) * and optimizing register allocation across complicated control flow (like language interpreters or emulators) It can absolutely be worthwhile to write an appreciable portion of a program in assembly if these "features" make the code significantly faster or even easier to express.
- dllthomas 12y ago'It can absolutely be worthwhile to write an appreciable portion of a program in assembly if these "features" make the code significantly faster or even easier to express.' Strictly speaking, yes. I would urge some hesitancy in concluding that is the case, though. WRT the first, you take some portability penalty for using GNU extensions, but that is probably significantly less than you take by writing in assembly. Unless you're targeting an architecture GCC does not target and your alternative compilers don't have a similar extension, you should still not be writing assembly for this reason alone. "Directly accessing status flags like the carry flag (necessary for efficiently implementing bignum arithmetic and CPU emulators)" This falls under both "hardware access" and speed. It certainly is a reason to occasionally break out the inline assembly. "and optimizing register allocation across complicated control flow (like language interpreters or emulators)" This is a very bad reason until it actually proves strictly necessary (at which point it falls back under speed and/or size). Modern compilers are quite good at register allocation and getting better, and chip architectures are complicated enough that you're likely to be wrong about what's fastest and/or best. The ability to rapidly try new things will probably get you faster results faster - compare the time taken tweaking optimization flags and rebuilding, versus working out an alternative register allocation and threading it through all the relevant code. Moreover, a small change in requirements can entirely invalidate all of that work. An understanding of assembly and your target architecture sufficient to allow you to allocate registers by hand is still highly valuable when you get into that space, though, so you understand what you're looking for when comparing generated code and benchmark results.