4 ms·
> Assembly has one huge advantage over C: no undefined behavior. In the olden days, maybe, but nowadays? No way. As the most extreme example: forget to use mem
by gecko 11y ago
> Assembly has one huge advantage over C: no undefined behavior.
In the olden days, maybe, but nowadays? No way. As the most extreme example: forget to use memory barriers when you should? Congratulations, the OOO nature of modern day CPUs means your code may not execute identically on all platforms. But even lesser things can impact you: instructions that were cheap become expensive, or suddenly registers that you know you weren't supposed to touch but did (and that happened to work) suddenly don't because a library got changed, or half a dozen other things.
With assembly on a modern CPU, congratulations: you have eliminated one level of abstraction. But there are still many, many turtles to go before you're really all the way down.
- ndesaulniers 11y ago> instructions that were cheap become expensive Agree. At which point, C gives you a huge advantage. Sure, you can hand write assembly, but I bet the libc implementation you're linking against has optimized to death with intimate knowledge of timing sequences and inner state of the processor from the processor vendor. I would expect a company like Intel to contribute patches to glibc (GNU libc) based on running functions from the standard library on a very very expensive FPGA (or just expensive-software simulation of hardware). Memory ordering operations are an advanced topic; I have a copy of C++ Concurrency in Action, currently sitting on my bookshelf, that has a chapter explaining the concepts. Should be a fascinating read!
- pcwalton 11y agoAgreed. I think there's no clearer example of C giving you an advantage than integer division by a constant. Even on architectures where it's supported (x86), the divide instruction is really slow. The standard approach is to use the Hacker's Delight technique to convert the division into a fixed-point multiplication and shift. All production-quality compilers will do this for you by generating the magic number, but if you're doing it yourself in assembler you'd have to look up the magic number and shift. Lots of assembly language programmers won't even bother doing this and will just write "idiv" in x86 (or "bl __divsi3" on ARM), which slows down their programs.
- pjc50 11y agoI think you might be being optimistic about Intel there. They have their own compiler suite though, which can be a few percent faster than GCC and has better auto-vectorisation. It's almost the other way round: they have a corpus of binaries to use when making processor design decisions.
- Someone 11y ago"In the olden days, maybe" Nope. I expect _all_ early processors had undefined behaviour, because they didn't have the transistor budget to make all instructions behave predictably. The 6502 certainly had (http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes http://www.ffd2.com/fridge/docs/6502-NMOS.extra.opcodes), as did the Z80 (http://www.z80.info/z80undoc3.txt http://www.z80.info/z80undoc3.txt)