4 ms·
Don't go there. There's really not a lot of work. But if you must, low level is more a calling than a learned skill. You probably shouldn't be learning assembl
by CalChris 10y ago
Don't go there. There's really not a lot of work. But if you must, low level is more a calling than a learned skill.
You probably shouldn't be learning assembler. First, compilers are really quite good. Yes, it's possible to beat them (I do) but generally not by much. And not by much ain't gonna put bacon on the table. You can probably get what you need from gcc inline asm() calls. Take a look at the linux sources and figure out why and when assembly is used there:
http://stackoverflow.com/questions/22122887/linux-kernel-assembly-and-logic http://stackoverflow.com/questions/22122887/linux-kernel-ass...
Secondly, writing in assembler is not low level. You just think it is. You should really be understanding caches and you can improve your cache performance in C.
Anyways, unless you deeply know what's going on inside of the microarchitecture of a modern superscalar, out of order, speculative, renaming, μop-cached, hyper-threaded, multicore beast then you shouldn't be fooling yourself by writing in assembler.
http://blog.erratasec.com/2015/03/x86-is-high-level-language.html http://blog.erratasec.com/2015/03/x86-is-high-level-language...
Unless you've really read Intel's Intel 64 and IA-32 Architectures Optimization Reference Manual (and ARM's Cortex®-A72 Software Optimization Guide) and meditated on the suras of Agner Fog's Microarchitecture you won't even know what's going on with something as simple as mov RAX, RBX.
Look, most compiler writers don't even know this stuff (Intel C Compiler yes, llvm occasionally) and frankly, it isn't very useful because Intel spends a billion dollars a year to make your bad x86 code run reasonably fast. Consider a switch statement which compiles into an indirect branch, jmp reg. That branch has to be predicted by the BTB before the jmp reg instruction is even fetched and that's really hard to do. Every year they get better and better to the point that you're not even aware of it. But if you want to the help the CPU out, you could put a UD2 right after the jmp reg. This is insanely hard to understand and will help very little.
Don't go there.
- pdelbarba 10y agoTo add to this, most micros these days are ARM based which are specifically designed to not need assembly in their boot code. I basically never use it anymore. That said, you should have some understanding of what C code will map to what assembly for the purposes of memory management and performance. Also: to say its a calling is accurate. I love what I do because what I create is physical and interacts with the physical world. I can hold my projects in my hands and say "I made this". I've done web and desktop stuff and can say that this work is significantly more fulfilling to me.
- vvanders 10y agoGood stuff. I'll add that while full-time native work may be in short supply, it's an awesome skill to have in your belt. You many not need it often but when you're suddenly up against limits where current technology doesn't suffice(Java/Python/Ruby/etc) it can seem like magic to break down into the lower stack and get 10-50x performance boost. Having that escape hatch available is incredibly valuable and for me distinguishes the engineers I hold in high regard.
- gspetr 10y agoIf one wants to learn to reverse engineer software what choice is there but to learn assembly?
- dom0 10y agoLearn to read, understand and map back into C is something different than programming in it.
- briansteffens 10y agoI agree not to go into low level programming expecting a wealth of job opportunities to suddenly open up, but I wouldn't tell people not to go there at all. Not only is assembly really fun to play around with, I feel like I've gotten a lot out of the bits of assembly I've read/written. Even though I've never written assembly code for work, being able to read the disassembly in gdb has come in handy before. Also, a lot of the subtleties of C/C++ never quite clicked for me until I had an idea of how the generated assembly would work. It's similar to learning a functional language. I have no idea if I'll ever use Haskell professionally but learning a bit of it has been a good way to see problems and logic differently. I think both assembly and Haskell have made me a better programmer, even if I never become truly proficient in either or use them directly in my job.
- inetknght 10y agoIt really does give you insight into some of the lower level stuff. It won't give you the full picture but it will give you ideas about how you might be able to take better advantage of your hardware by changing how you use data.
- pacman128 10y agoTotally agree. When I taught x86 assembly in college (in the 90's), the goal of the class was to give the student a better idea of how things worked under the hood to improve their C programming, not to be an assembly programming. Just today, I helped a coworker debugging a segmentation fault that occurred in a library where the debugging info was stripped out by looking at the assembly code.
- inetknght 10y ago> Just today, I helped a coworker debugging a segmentation fault that occurred in a library where the debugging info was stripped out by looking at the assembly code. Being able to debug applications which don't have debuginfo (particularly optimized builds) is highly valuable though.
- throwaway777836 10y agoAs an embedded programmer, I wholeheartedly second this. I'm in an area where there are relatively few opportunities to do close to the metal work. The ones that do, don't pay any more than backend web developers make. In fact I've come to assume that they can offer less due to either the intrigue of the work, or because you often compete with computer/electrical engineers who aren't expecting outsized developer salaries. Likewise, while I have loved the skills I've learned in embedded and low-level work, working at an embedded shop has taken a lot of the joy out of the learning. You trade off an inherent rewarding development environment with the realities of developing against hardware, where project cycles are long, you're often dependent on horrible vendor APIs and support, and where everything moves much slower. The counter to that is the type of work I believe you're describing, which sounds like HFT optimization on Intel. I got into embedded because I wanted to eventually end up there, but again, it's an extremely limited market. And as someone who has indeed dabbled in the Fog optimization manuals, you quickly learn to realize how much the ROI of assembly isn't worth it. The future of speed isn't going to be going lower down the programming stack. It's going to be in new hardware: FPGAs and ASICs, writing RTL for system specific CPUs. And that is highly exciting, though it necessitates a pure programmer has to learn hardware at a deep level as you imply. As for me, I concur with the statements others are making about using my skillset for security research and reverse engineering. Working in embedded development has bored me to tears, and taken the magic out of learning to love the skills themselves. I'd much prefer to work at a pace that isn't limited by the pace of a cross functional team of software and hardware engineers. Learn the skills, yes, completely. The knowledge is worth it. But for the love of God, don't get expect to get joy out of working in it.
- aswanson 10y agoCould not have said it any better. Embedded development is dominated by hardware engineers who make decisions very often without the software development teams input, placing embedded folk square in the target of management angst as well. Choosing Broadcom chips without drivers, 3rd party experimental hardware who wont release data sheets, choosing USB chips that don't support host mode, miswired memory interfaces that mismap fpga access, FPGAs that cause spurious bugs when consuming more power than necessary in certain modes, all lay squarely on the embedded devs shoulders and can manifest at first looking like pure software problems with the schedule pressing. Not a pretty world.
- scruple 10y agoI've been telling people since the late 00's that starting my career in embedded was the single best thing that happened to my career. I quickly follow that up with the fact that leaving embedded was the second best thing that happened to my career. I've dreamed about going back, because I do miss it, but the jobs aren't there (in my area and especially now that I've fallen in love with full-time remote work). I know a hell of a lot more about what our code is actually doing up and down the stack than my colleagues, including most of the managers I've had and "Principals" I've worked with and so on. It helps, a whole lot, in fact, and I find that it's personally rewarding, but it doesn't amount to much more than being the person who gets asked the challenging profiling/performance/optimization questions.
- joesavage 10y ago> First, compilers are really quite good. Yes, it's possible to beat them (I do) but generally not by much. Genuine question: what would you quantify “not by much” as here? In my experience, it's not uncommon to see 2x+ speedups from well-written software pipelined hand-optimised assembly in hot loops. (Especially so for in-order processors, like you might see in embedded applications or as a LITTLE core in your smartphone.)
- CalChris 10y ago2x in a hotspot is not much compared with better cache management in the rest the program. But if that 2x is important, great. I know this sounds really boring but you should write it in C first and then find that hot loop in a profiler like VTune and then rewrite. 2x of something really unimportant is still unimportant. Also while software pipelining is possible on something like Haswell ... its limited register set makes it a limited technique. Modular variable expansion is tough with not so many registers but renaming does help somewhat. I think tools like VTune are awesome for finding hotspots and reading assembler is like reading Latin. But programming in assembler? I think it's best to disassemble and rewrite your C accordingly. I should have mentioned this in the first post: if you're not a VTune ace, if you're not looking at the Intel PMRs and scratching your head, you probably should not be writing in assembler in 2017. Also, VTune deals with C (and Java) quite nicely (just not on OS X). Anyways, you may get 2x+ on something but that approach won't work with a GPU. Similarly, Apple doesn't provide microarchitectural information on the a10. Nvidia doesn't on Denver. Even though assembly will still be with us, this low level approach is going away. Apple, Intel, Arm, Nvidia, ... really want you to write in C. I say all this as a hardcore knuckle dragger.
- peterkelly 10y agoSomeone has to write those compilers. Those with the skills to do so are vital to the industry. If we want more nice high-level languages and improved operating systems, we need new people entering this area of software engineering. Otherwise, where is the next iteration of systems software going to come from?
- CalChris 10y agoLLVM backend developers generally write in TableGen. Their assembly knowledge to say nothing of their microarchitectural knowledge is limited. That may sound harsh but it's actually the point of a good compiler design (which LLVM has). You can write an optimizer pass without understanding the C parser. You can write a backend without understanding register allocation. You can get something working without really getting it tuned. You can specify superscalar machine instruction scheduling latencies without really understanding instruction scheduling itself. https://github.com/llvm-mirror/llvm/blob/master/lib/Target/AArch64/AArch64SchedCyclone.td https://github.com/llvm-mirror/llvm/blob/master/lib/Target/A...
- _pmf_ 10y ago> Anyways, unless you deeply know what's going on inside of the microarchitecture of a modern superscalar, out of order, speculative, renaming, μop-cached, hyper-threaded, multicore beast then you shouldn't be fooling yourself by writing in assembler. Assembly is useful for understanding early initialization code for embedded platforms (startup file). Depending on how aligned the vendor's board support package is with your actual target, you might have to touch this, and since this code runs at a time where there is neither stack nor heap (can't have a stack unless the stack pointer has been set up), this is easier in assembler than in the stackless C variant that you might coerce your compiler to support. The same applies to debugging issues bootloaders, where you'll have to inspect how the reset vector looks.
- linkregister 10y agoThere are plenty of reasons to know assembler besides performance. I am completely ignorant of all the pipelining mechanics you discussed but have gotten paid to use assembly for years. 1. Writing embedded software. You're not going to get very far if you don't know how to set up your memory, text section, etc. 2. Debugging embedded software. Good luck interpreting your JTAG output if you don't have a good knowledge of assembler. Even if you get to use gdb/Wind River Debugger/etc., you will want to be able to tell what is happening. Symbols only go so far. A backtrace will get messed up and you'll need to look at the stack to figure out what happened. An access violation will occur and you'll need to figure out what line of code it corresponds to. 3. Debugging without source code. Same as #2, even more difficult. 3. Reverse Engineering. You are trying to figure out what is happening in a proprietary driver binary blob (such as NVidia's Linux driver). You are trying to figure out how to get your software to work with an ancient piece of software whose author has long since been out of business. Even if you have the cash for Hex-Rays decompiler or can readily use the Hopper decompiler, this code is simply not high-level enough to interpret without knowing assembly and having a deep understanding of the stack and memory. 4. Vulnerability research / hacking. You are writing an open-sourced client for a proprietary protocol, looking for a memory corruption vulnerability, etc. You can pretty much forget it unless you know assembly.