7 ms·
A Friendly Introduction to Assembly for High-Level Programmers
- aatd86 2y agoGood stuff. My level was over 9000 :o)
- westurner 2y ago- "Ask HN: Best blog tutorial explaining Assembly code?" (2023) re ASM, HLA, WASM, WASI and POSIX, and docker/containerd/nerdctl support for various WASM runtimes: https://news.ycombinator.com/item?id=38772493 https://news.ycombinator.com/item?id=38772493 - "Show HN: Tetris, but the blocks are ARM instructions that execute in the browser" (2023) https://news.ycombinator.com/item?id=37086102 https://news.ycombinator.com/item?id=37086102 ; the emu86 jupyter kernel supports X86, RISC, MIPS, and WASM; and the iarm jupyter kernel supports ARMv6
- dmitrygr 2y agoWhy does it say “constants here” in .data? .data is for initialized variables. Constants go into .rodata
- shikaan 2y agoYou are correct. The focus of the series is in on accessibility. Sometimes it comes at the expense of telling the whole story: I was even on the fence on introducing the .bss block, honestly. The article mentions initialized variables, but maybe this warrants a footnote. Thanks for the feedback and for reading through the article. I appreciate a lot :)
- aleph_minus_one 2y ago> The focus of the series is in on accessibility. Teaching wrong things does not make the article better accessible, but more confusing.
- Nab443 2y agoI would add that if you're targeting HL programming language users, this is something they should already have the knowledge of. It does not need a particular effortt to map that to what they alrady know.
- shikaan 2y agoYou got me thinking and I simplified the whole block. Removed the .bss part and just calling what goes in there "data". Thanks once again for the feedback :)
- keyle 2y agoI've been on Apple silicon since they've been out, I'd love a similar intro but based on this architecture.
- jdshaffer 2y agoHere are some simple programs in assembly for the M1 chip, annotated as best as possible. Perhaps they will help? https://github.com/jdshaffer/Apple-Silicon-ASM-Examples https://github.com/jdshaffer/Apple-Silicon-ASM-Examples
- htk 2y agoThank you for the repository. I'm having a great time reading the code with all the comments. (The note about writing on a Oculus Quest had me cracking up.) You could easily write a great blog post with this content, or do some YT videos. The Apple's ARM assembly ecosystem is short on resources like this.
- jdshaffer 2y agoThank you for your kind comments, and I'm very glad you like the samples. I actually can't remember what I wrote with my comments, though I tend to not take myself very seriously. smile I'm not an expert with M1 assembly, just a tinkerer, so I never felt wise enough to write a blog or record videos. I wish I could have found some for myself!
- bigbacaloa 2y ago[dead]
- mamonster 2y agoBiased opinion(because this is how I did it in uni): Before looking at modern x86, you should learn 32-bit MIPS. It's hopelessly outdated as an architecture, but the instruction set is way more suited for teaching (and you should look at the classic procedure from Harris and Harris where they actually design a pipelined MIPS processor component by component to handle the instruction set).
- inopinatus 2y agoI might also suggest ARM. Way back in the day, one of my first-year CS modules included writing a rudimentary MIPS emulator for much the same reasons as above, but I came to that knowing 6502, x86 and ARM2 assembler already, having cut my teeth on Acorn stuff, and at the time I still preferred ARM2 out of all these for clarity. ARM obviously remains relevant today, albeit with many revisions.
- aleden 2y agoAre delay slots unique to mips? They're a pretty significant aspect (complication) that I don't see anywhere else. Also, the gp register- don't know of any other arch where you need to set something like that up to access global variables. It's another layer of indirection which makes the assembly code harder to read (especially PIC code that works off of the value of the t9 register)
- TapamN 2y ago>Are delay slots unique to mips? No, several other architectures of that period have delay slots (80s/90s), and modern VLIWs/DSPs still often have them. Sometimes the slots longer than a single instruction.
- drmpeg 2y agoSPARC has delay slots. Here's some code. The clr %o3 and restore %o0 are in the delay slots. 10082410 9de3bf98 save %sp, 0xffffff98, %sp 10082414 90102001 mov 1, %o0 10082418 92100018 mov %i0, %o1 1008241c 94100019 mov %i1, %o2 10082420 7fffff17 call dirList 10082424 96102000 clr %o3 10082428 81c7e008 ret 1008242c 91e80008 restore %o0
- jshaqaw 2y agoNothing gave me an intuition for assembly like TIS-100
- packetlost 2y agoI have a nice print copy of the Shenzhen IO manual. I love those games so much, and agree that they're actually not a half bad way to get started with assembly!
- unwind 2y agoVery nice, I'm always for more assembly-level programming and education! A very minor grammar thing, here: In our example, the mnemonic is mov, which stands for move, and the operands are rax and rbx. This instruction in plain English would read: move the content of rbx in rax. I believe the last part would be better as "... content of rbx to rax", i.e. "to" instead of "in". I'm not a native speaker, though.
- danwills 2y agoAgreed, indeed I thought that "Copy the contents of rbx to rax" might be even clearer (mov doesn't remove the value from rbx IIUC!)
- delta_p_delta_x 2y agoI'd say 'Yoda speak' makes translating from Intel syntax to English a lot easier. mov rax rbx Into rax, copy the contents of rbx.
- genewitch 2y agoif you tell someone you're moving, a generalized first question they would ask is "where?" not "what". move Fiji belongings
- shikaan 2y agoThanks for the comment and for taking the time to read :) I fixed it and it flows much better now
- donpdonp 2y agoReally well written - it was a pleasure to read. Concepts were introduced in small, consumable chunks, without being too slow or overwhelming. I hope more articles are coming.
- shikaan 2y agoThanks for the kind words! Yes, there's more coming. I planned a series of seven articles, the second of which is already out
- kwar13 2y agoThat was a nice little tutorial!
- mathpax 2y agoExcellent post. Thanks for your time and effort.
- TacticalCoder 2y agoAs someone who used to eat assembly instructions for breakfast back in the days and remembering when a MUL was taking more than 1 cycle, is there any resource you'd recommend to learn about using the highly vectorized/parallelized instruction sets in modern CPUs? I know about Daniel Lemire / lemire.me Anybody / anything else you'd recommend?
- 201984 2y agohttps://uops.info https://uops.info
- TacticalCoder 2y agoOh wow, tyvm: I looked a little bit already and it looks like a treasure trove. Very extensive.
- dzaima 2y agoThere's https://www.agner.org/optimize/microarchitecture.pdf https://www.agner.org/optimize/microarchitecture.pdf for a bunch of microarchitectural information, covering many interesting things outside of specific instruction breakdown as in uops.info. chipsandcheese.com also covers a bunch of stuff. Then there's various more specific things in a bunch of places, e.g. http://www.numberworld.org/blogs/2024_8_7_zen5_avx512_teardown/ http://www.numberworld.org/blogs/2024_8_7_zen5_avx512_teardo..., https://web.archive.org/web/20240602004718/https://www.mersenneforum.org/showthread.php?p=614191 https://web.archive.org/web/20240602004718/https://www.merse..., and a bunch more. https://dougallj.github.io/applecpu/firestorm.html https://dougallj.github.io/applecpu/firestorm.html for Apple M1.
- stonethrowaway 2y agoOne thing I don’t like about these articles in general is they omit a very important step in describing assembly: how it’s actually used by a computer. I’ll give a brief intro to folks and hopefully not confuse things any further. If you want hands on experience, grab an STM32 Nucleo board, or do Ben Eater’s 8-bit processor DIY course. This is now getting into a very closely related subject matter called Embedded Systems via foundational electronics and electrical engineering studies. Anyone interested in this - may the Gods be on your side. So, here we go. Blog post as a comment. Assembly and mnemonics are there to be human readable representations of a fictitious thing called bits which are always “stored somewhere”. Now, bits don’t actually exist, nor does their storage, but voltage differences, magnetic/electric fields and currents do. There are no intermediate layers in hardware that translate your “program” into this pattern - your “files” already exist in as this pattern somewhere because again, it’s voltages, fields, and currents, and that’s all there is. This means all those abstractions and OSI layers don’t exist - all that stuff is make-believe. Files and file systems don’t exist. Hence, assembly doesn’t exist. I’ll skip over a thing called microcode and microarchitecture. Both of these deal with taking your bit pattern and re-arranging it into a different pattern that the exact processor you’re using is optimized/carefully designed for and doing other mean things to your program. In general you wont encounter this when doing assembly or any other high level language, but certain processors do allow for some play at program-level. You can configure the processor exactly how you want it to function and this is packaged with your program code. Now, when we talk about data buses, instruction buses, “cache lines”, and all these things what we are really talking about are parallel traces on a circuit board on which one can sample, usually though not always, a voltage difference on each trace and see if it’s “high” or “low” (your “bit”). The number of these traces usually corresponds to the number of bits. Hence, an 8-bit, 16-bit, 9-bit and a 32-bit processor again, usually though not always will have physical lines on a circuit board corresponding to this number. Hence, your assembly instruction is an English term for an ordering of these lines at a point in time. Here’s the OG 8086 processor chip. You can see physically it has AD0 to AD15 pins, hence 16 “bits” of voltage levels that are “high” or “low”: https://www.geeksforgeeks.org/pin-diagram-8086-microprocessor/ https://www.geeksforgeeks.org/pin-diagram-8086-microprocesso... So your assembly instruction is an arrangement of the voltage levels for these pins. The processor samples it, and proceeds to raise or lower other pins it has. And it goes round and round like this until it overheats and dies on you after some years of abuse. You write your program, you store this in “memory” as an ordered arrangement of voltages/fields. A “controller” reads this and presents the processor at any point in time with the voltage levels, directly hooked up to its pins. The processor goes ahead and does it’s thing. There’s very little rocket surgery to it. Processors of course are not usually this simple. They are nowadays structured do many steps at once, often times abusing a clock (again, voltage differences) and decreasing sizes of chips to go faster and faster. One point to mention here is, you can probably now see that the data pins of something like an 8086 can literally be hooked up to anything - there’s no separation between “code” and “data”. By now you should understand that these, too, are make-believe. A pattern of signals is a pattern of signals no matter where it’s coming from. Although some processors will tell you otherwise and they get fancy with a thing called memory maps. They too, don’t exist. So, armed with this hopefully demystifies for you a bit the why of assembly. It’s a convenient, human readable form of instructions that a processor can execute. It is a fairly banal and trivial thing in the end. The real guts of it is knowing how the processor will execute it, what it will do before and after. Assembly as a language can be picked up relatively quickly. It should be noted that, should you choose to, you can open up the manual of your favourite processor, and chances are highly likely you’ll get a listing of not only mnemonics (for your reading pleasure), but the aforementioned voltage levels and functions of each of the of pins, as well as the “bit pattern” for each instruction. Some manuals will, if you’re really lucky, tell you how to design your circuit board for the processor to function properly, how far your memory is allowed to physically be from the processor, and what other things you must keep in mind. Clear as mud? (epilogue: if you’ve found this info tickles your fancy, you should definitely look into electronics and start building circuits, both analog and digital ones, get comfortable with reading data sheets and understanding how processors interact with the peripherals around them to perform their duties. This is an immense field of lots of things which would fascinate you and are truly science fiction.)
- jjkaczor 2y agoThis is a nice introduction! Myself, I started with Jeff Duntemann's "Assembly Language Step By Step" - http://duntemann.com/assembly.html http://duntemann.com/assembly.html (He is a an engaging tech author - I have never not loved one of his books)
- pjmlp 2y agoDo yourself a favour and use a good macro assembler, and if doing x86, Intel syntax.
- rep_lodsb 2y agoA comment on the second blog post: Some condition codes are different depending on signedness of the numbers being used. "Greater"/"Less"/"Overflow" are for signed, "Above"/"Below"/"Carry" for unsigned. The sign flag by itself is not what you would test when comparing two numbers, since the subtraction done by CMP might have overflowed - that's why the condition for "Less" is defined as "Sign XOR Overflow". There are various arguments for always using signed types in C, but none of that applies to assembly, and unsigned is more appropriate in most cases. So maybe these conditions should be introduced first? Readers might be confused why it is called EFLAGS, or about the register names, so maybe a little history should be included: registers were originally 16 bits, then "E"xtended to 32 bits, and later "R" was used to indicate 64 bits. AH/CH/DH/BH correspond to the high byte of the 16 bit registers AX/CX/DX/BX, not the extended ones. These aren't used much anymore. Good tutorial nonetheless! So many others don't even mention that official documentation by Intel / AMD exists. Instead it's mostly "here's what code GCC/Clang generates for this C program", in that horrid AT&T syntax, and links to one of several third-party reference sites containing nothing but giant dense tables of mnemonics, opcodes and flags. No wonder when people reading those come away convinced that it's impossible to actually understand this stuff.
- shikaan 2y agoHey, thanks for the feedback (: The second article is still shaping up, but I felt like publishing it to get some early feedback. What you mention are a couple of the reasons. At this point, I find it too dense (and it was even more so in first drafts) hence missing information. Maybe I should cut some parts, like the rip intro, and accommodate for more details about flags and conditions. This is good signal for me. Thanks again for taking the time