12 ms·
x86 assembly doesn’t have to be scary (2018)
- agumonkey 5y agoSomehow seeing prolog, APL, sml code made me think in terms of small combinators that felt a lot like assembly.
- JoeAltmaier 5y agoYou resort to assembler for critical operations or performance. Having a nice, clean orthogonal instruction set helps none of that. So while 68000 ASM may look pretty and be easy to remember, its obvious why x86 won - you could get the critical jobs done.
- tenebrisalietum 5y agoI do know x86 for example has things like the STOS/STOSB/STOSW/STOSD which specifies a lot of behavior for a single instruction, and combined with the REP prefixes is a pretty elegant way to do memory block operations. I don't think 68000 had anything like that.
- JoeAltmaier 5y agoTo be fair, Intel nerfed those instructions for a long time. See, DOS was using REPNZ STOSW for timing things. So as the processors got faster, those instructions didn't, so as to make DOS BIOS continue to operate correctly. It was a terrible time for x86. At the same time, I used a clever 12-byte sequence of those opcodes to swap software interrupt vectors on process switch. So each process could have its own floating-point exception handlers etc. We called it the 'soft vector chain' and it was among the least known parts of our kernel. A colleague (John McGinty) suggested in our old age we could consult by scratching our beards and saying "Ah! It must be the soft vector chain!" for every problem.
- inkyoto 5y ago> its obvious why x86 won - you could get the critical jobs done. It is a bit less obvious, in fact. Motorola never looked at 68k CPU's as a serious business, more like toying around with the CPU's all the time or looking at them as a less important spin-off of the main business. Their main sources of income were defence contracts (e.g. specialised or hardened microchips), microcontrollers, DSP's (which were pretty cool, by the way, – all implementing the Harvard architecture), memory chips (I think), radios and the field radio equipment and later mobiles. They carried largely the same attitude to 88k RISC and PowerPC CPU lines (albeit trying to compete more seriously for a while), but ultimately failing to catch up and leading to the eventual PowerPC demise. After that failure, they spun off anything CPU, DSP and microcontroller related into Freescale, and the rest is now history.
- andrewshadura 5y agoThis webpage hijacks the keyboard in a very nasty way, disabling not only scrolling, but also a bunch of other functions.
- heinrich5991 5y agoUp/Down/PgUp/PgDown/CTRL-F all work for me. What's disabled for you?
- andrewshadura 5y agoAll of those. Also F12 doesn't work, so I have to use the mouse to inspect the internals.
- benjojo12 5y agoReally? (Author here) What browser are you using?
- erik-smit 5y agoI have similar issue with Chrome 94 on Windows. It's fine when I initially open the page, but once I click 'run' I can no longer use PgUp, PgDn, F12, etc. I'm guessing the emulator captures some input. But even when clicking on other parts of the page, it doesn't 'uncapture'. FWIW, it doesn't really bother me.
- p_l 5y agoHappens to me as well (current chrome w/ vimium on mac), but only after running the example in the emulator. Before hitting the emulator (and/or editor, not sure) all keys work fine. After, well, only scroll on the mouse worked for moving through the page.
- _8j50 5y agoI feel like X64 doesn't get enough love these days. I think new tutorials should be X64 first and then after you get a hang of it talk about X32. It's harder the other way around, especially when it comes to calling conventions.
- Ygg2 5y agoUmm, did anyone read the reference manual for x86_64? Intel's big enough to kill a goat (~2000). Add AMD on that and you can kill a small tribe of goats.
- sabas123 5y agoDepending on what you're after there is a lot more than 2000 pages of documentation :) That said, the C standard is also an impenetrable mess, yet people can start using it without resorting to it.
- Ygg2 5y agoIf you are reaching for assembly, usually that means digging into some optimizations. Those are highly obscure.
- _8j50 5y agoThere are not that many compiler generated instructions both for X32 or X64 if you look at it by percentage of code. You have to look up the manual for rare instructions no matter what, you hardly need to read maybe a dozen pages to know enough to understand the common operations and control flow. My argument if you start with the current arch, that will be your frame of reference instead of X32 (why not X16 if earlier is better?)
- mike256 5y agoI think it's much easier to begin with x86. Especially when the assembled code is being run the way it is on this website. x64 is a little harder because just the switch to x64 mode alone almost fills the boot sector.
- begueradj 5y agoI learned x86 at university. I miss it.
- Koshkin 5y agoYou don't have to: Windows programming using NASM is easy:) ; To build: ; nasm -fobj hello.asm ; alink -oPE -subsys con hello -entry main bits 32 import imp_CreateFileW kernel32.dll CreateFileW import imp_WriteConsoleW kernel32.dll WriteConsoleW import imp_CloseHandle kernel32.dll CloseHandle import imp_ExitProcess kernel32.dll ExitProcess import imp_GetLastError kernel32.dll GetLastError extern imp_CreateFileW extern imp_WriteConsoleW extern imp_CloseHandle extern imp_ExitProcess extern imp_GetLastError %define CreateFile [imp_CreateFileW] %define WriteConsole [imp_WriteConsoleW] %define CloseHandle [imp_CloseHandle] %define ExitProcess [imp_ExitProcess] %define GetLastError [imp_GetLastError] global main section .text use32 main: push dword 0 ; hTemplateFile = 0 push dword 0 ; dwFlagsAndAttributes = 0 push dword 3 ; dwCreationDisposition = OPEN_EXISTING push dword 0 ; lpSecurityAttributes = NULL push dword 2 ; dwShareMode = FILE_SHARE_WRITE push dword 0x40000000 ; dwDesiredAccess = GENERIC_WRITE push dword filename call CreateFile mov [handle], eax push dword 0 ; lpReserved = NULL push dword nChars ; lpNumberOfCharsWritten push dword 16; nNumberOfCharsToWrite push dword hello ; lpBuffer push eax ; hFile call WriteConsole mov eax, [handle] push eax call CloseHandle push dword 0 call ExitProcess err: call GetLastError push eax call ExitProcess section .data use32 filename: db __utf16__('CONOUT$'), 0, 0 hello: db __utf16__('Hello Console!'), 13, 0, 10, 0, 0, 0 handle: resd 1 nChars: resd 1
- wiz21c 5y agoLong time ago I coded much of my professional stuff in assembly, I was hired specifically to optimize stuff. But it was 20 years ago, compilers were not very smart. How smart are compilers these days ? Say, to optimize small function, for example computing a scalar product or applying a 3D matrix transformation to a set of points.
- deleted 5y ago[deleted]
- thegeomaster 5y agoPretty smart. The examples you gave are math-heavy, so to get the best performance you need to do use some kind of SIMD instructions. For these you need to drop down a level, although not really assembly - there are compiler intrinsics that you can use. And for simple functions, compilers are getting fairly good at autovectorization, meaning to introduce SIMD instructions automatically. But it's not something you can rely on. Generally, they do lots of inlining, and then once you inline you can get some more optimizations in, rinse and repeat. Ends up pretty optimal. (This is C++, can't speak for other languages.) We work on very perf-sensitive code and we never drop down to assembly. For hot loops, we usually inspect the generated assembly and if it's not great, it's fairly easy to "nudge" the compiler towards the better-performing solutions by tweaking the source code. Also some manual unrolling might be needed to better saturate the vector processing cores of modern CPUs. And when you're working with signed integers, you still have to do stuff like a >> 1 instead of a / 2 :)
- wiz21c 5y agoIf it was on StackOverflow, I would give it a "correct answer" flag :-) But if it's now up to some nudging, it's vastly better to me. I provided math stuff and vectorisable stuff on purpose :-) Happy to see that vectorisation is somewhat automatic. I remember the MMX days and there were not that funny :-)
- flohofwoe 5y agoIME: "it depends". You'll have to check the generated assembly code and then tweak your "high-level" C code to appease the compiler to generate code that's acceptable. Sometimes a small change in the high-level code is enough to break the "pattern matching" in optimizer passes. Here's an example that looks like magic at first glance where the compiler converts manual bit twiddling code to a popcnt instruction (with the right compiler setting), but do the bit counting any other way, and the whole thing falls apart: https://www.godbolt.org/z/KaM6jWjdx https://www.godbolt.org/z/KaM6jWjdx
- flohofwoe 5y agoI sometimes wonder whether assembly code would even be considered "scary" today if IBM had picked the Motorola 68000 instead of the Intel 8088 for their PC. The x86 instruction set was a cobbled-together mess from day one, while 68k assembly coding was pure joy because of its elegant and consistent instruction set.
- Koshkin 5y agoIdeally - ideally IBM would have created and used their own microprocessor based on the System 370 architecture. But no - for them the PC was a glorified typewriter: even PS/2 (based on 80286) was mostly positioned for use merely as a "smart" terminal for mainframes. So, today the entire world is basically run on faster "typewriters" (sometimes enhanced to include "windows" - even on the server side).
- mjbrusso 5y agoI agree. 68k was one of the most orthogonal architectures ever.
- inkyoto 5y agoAfter the PDP-11 architecture, yes.
- Taniwha 5y agowell except for the two sorts of registers
- Joker_vD 5y agoThree, starting with 68040.
- a-priori 5y agoAnd likely far more by now, had it become the PC instruction set architecture. The x86 instruction set was also simpler back in the late 70s, in the 8086 era when the Motorola 68000 was first released, than it is now. Back then it only had the one register width (16-bit, e.g. "ax"), whereas now it has the 32-bit series (e.g. "eax") series and the 64-bit series (e.g. "rax"). It also now has SIMD, SSE/AVX, virtualization support, and other technologies. Back then it just had one operating mode (real mode), whereas now it has protected mode, long mode, system management mode, and a few other intermediate modes (e.g. "unreal mode"). So a lot of the complexity that x86 has now was introduced after that decision was made. It's definitely conceivable that the 68000 line would have developed similarly had it been chosen instead of x86 for the PC.
- DonHopkins 5y ago>x86 assembly doesn’t have to be scary ...just ugly.
- Joker_vD 5y agoIt doesn't matter that much, really. What truly is ugly is interfacing with the rest of the computer, ugh. You can't use the VGA BIOS from x64, so go-o-o-od luck doing it via PCI. And properly setting up IOAPIC?
- eatonphil 5y agoI know this article is about bootloaders but more generally there are two ways I've tackled x86 as a total noob: compile a simple language to like ~5 instructions [0, 1] and, separately, write an emulator for ~5 instructions that can run basic C programs [2, 3]. I think it's fairly common to recommend beginners to write a compiler but I think it's less common to actually recommend trying to emulate parts of x86. I think it's a particularly easy way to get started just because it's the architecture you already know or because its the architecture that all compiler tutorials use (if they don't use LLVM). And if you are a programmer you probably incidentally have gcc, gdb, and objdump on your system ready to help you out. Doing both compilers _and_ emulators really helped my understanding of x86 and C (even if I wasn't writing C). My background is in web development and my reason for doing these projects/writing is purely educational. [0] https://notes.eatonphil.com/compiler-basics-lisp-to-assembly.html https://notes.eatonphil.com/compiler-basics-lisp-to-assembly... [1] https://notes.eatonphil.com/compiler-basics-an-x86-upgrade.html https://notes.eatonphil.com/compiler-basics-an-x86-upgrade.h... [2] https://notes.eatonphil.com/emulating-amd64-starting-with-elf.html https://notes.eatonphil.com/emulating-amd64-starting-with-el... [3] https://notes.eatonphil.com/emulator-basics-a-stack-and-register-machine.html https://notes.eatonphil.com/emulator-basics-a-stack-and-regi...
- secondcoming 5y agoCompiler Explorer [0] is a godsend for seeing what the compiler is generating. For example, the codegen for some C++ that was discussed a few days ago [1] [0] https://godbolt.org/ https://godbolt.org/ [1] https://godbolt.org/z/cfYKqajMd https://godbolt.org/z/cfYKqajMd
- Decabytes 5y agoThe problem I’ve always had with learning assembly (arm in my case) was that I never really had a project to work on that would use any of that knowledge
- ThomasBHickey 5y agoWASM is a nice 'assembly' language to play with.
- not-elite 5y agoSame here, mostly doing math stuff on x86. There was a recent thread [1] optimizing some very primitive trig functions. I recently watched a djb interview where he talked about the importance of fully utilizing available hardware [2 at 5:15]. That can be a good starting point, although at work its usually easier to just consume more resources than to use what you've got more efficiently. [1] https://news.ycombinator.com/item?id=28209097 https://news.ycombinator.com/item?id=28209097 [2] https://www.youtube.com/watch?v=1svxNxG6hHc https://www.youtube.com/watch?v=1svxNxG6hHc
- deleted 5y ago[deleted]
- HappyMans 5y agoI am fascinated with bootloaders and kernel writing. I am not very good at it, but I am fascinated by it, and every so often I try to learn some more. It feels a bit like a useless skill to learn (legacy BIOS bootloaders, that is) given UEFI dominance. But it connects me with my childhood playing with 286es and wondering how to program them. I love articles like this that break it down. The biggest challenges so far have been getting the assembler to output the correct format (ie, 16 bit real mode) and learning inline assembler in C (and getting GCC to output the correct format).
- kingcharles 5y agoThis is the book I learned from in the 90s: https://www.amazon.com/Developing-32-Bit-Operating-System-Cd-Rom/dp/0672306557 https://www.amazon.com/Developing-32-Bit-Operating-System-Cd... It's basically "Writing an Operating System from Scratch for Dummies". I actually wrote my own graphical x86 OS starting from the code in there.
- HappyMans 5y agoThank you so much for the recommendation. Been looking for something like this for a while. Do you think it's a waste of my time to be learning this in 2021?
- kingcharles 5y agoI definitely don't think it is a waste of time. I found it really fascinating to find out how a PC boots up from zero and how a very basic kernel is coded.
- 7thaccount 5y agoSuper dumb question (haven't taken a microprocessors class in over a decade): How hard would it really be to custom build a chip that was really simple, but modern. I'm thinking like the 6502 in the Commodore, but much faster. Or is the complexity in x86 an inherent property of modern performance? I guess what I'm getting at, is could you build something that is actually pretty darn fast if you don't need to run a modern OS like windows or Linux on it, but keep it drastically simple? I've been thinking it might be neat to have a blazing fast NUC sized computer that just boots into some barebones forth sitting on top of a few assembly words. Maybe with just enough peripherals to do some actual work (like load from SD card).
- ampdepolymerase 5y agoIt's called a FPGA; a software defined microprocessor (most higher tier processors can be reprogram to a certain extent through microcode, but a FPGA is a specialised chip designed specifically for this). You can get ridiculously high performance for your specific application, but it will never excel at general purpose computing. Good enough for Forth, great for ML, DSP, and number crunching, bad for running random apps from GitHub.
- 7thaccount 5y agoI've used FPGAs before (also ages ago). I guess I could create a simple chip on an FPGA and run a Forth on that, but I was thinking something more physical.
- d_tr 5y agoBut would you not need to use an FPGA anyway for experimentation and prototyping? If you want something more physical, fast and small you need a spot at an actual fab. There is no other alternative. You might also want to take a look at the "Minimal Fab" technology. I found out about it a year or so ago and it looked really interesting!
- 7thaccount 5y ago
- Banjo911 5y agoI don't find retarded freaks scary. Just annoying as hell.
- pajko 5y agoNow let's talk about SIMD...
- Koshkin 5y agoAs my professor told once, "The only difference between programming in assembler and a high-level language is that you have to type more." I can confirm - early in my career I was able to sustainably produce more than a thousand lines of working x86 assembly code a day.