9 ms·
Let's Learn x86-64 Assembly (2020)
- 90s_dev 1y agoI came to the party way to late. A month ago, I found out asmjit was a thing, and now it's happily embedded in my app. But I don't know assembly! I tried to learn a few times since the early 2000s but the timing was never right. But hand written asm as a feature fits perfectly into my upcoming app, so now I am on a roll learning assembly! Here are some more resources I found so far: https://news.ycombinator.com/item?id=22279051 https://news.ycombinator.com/item?id=22279051 https://sonictk.github.io/asm_tutorial/#introduction/settingup/netwideassembler https://sonictk.github.io/asm_tutorial/#introduction/setting... https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatsheet.pdf https://cs.brown.edu/courses/cs033/docs/guides/x64_cheatshee... https://people.freebsd.org/~lstewart/articles/cpumemory.pdf https://people.freebsd.org/~lstewart/articles/cpumemory.pdf https://learn.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-170 https://learn.microsoft.com/en-us/cpp/build/x64-calling-conv...
- enjoytheview 1y agoHere's a really good free one: OpenSecurityTraining2 Architecture 1001: x86-64 Assembly https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+Arch1001_x86-64_Asm+2021_v1/about https://p.ost2.fyi/courses/course-v1:OpenSecurityTraining2+A... They also have RISC-V and many other for debuggers and reverse engineering tools (ida/ghidra for example)
- Razengan 1y agoI wish there were more articles and resources about modern ARM assembly. Not that I ever will or have programmed in Asm, but I like learning about it and imagining I will, and Intelisms feel so archaic and crusty in comparison.
- 90s_dev 1y agoThe first HN link in my comment addresses that. The short version: learn the earliest asms first, then progressively learn the newer ones until you get to today, and none of the knowledge will be wasted. Kind of like fast-forwarding.
- mjevans 1y agoI wouldn't say you are wrong, but I would also postulate. The smallest, simplest, 'useful' (in terms of useful enough that lots of devs did good work with it and thus it might also be 'popular') ASM sets are probably also sufficient to start with. Provided you've got a good guide to using them, and also ideally a good sheet for why given instructions are packed the way they are in binary. I do agree you're more likely to find pointers to such resources in more classic architectures. They're also more likely to be easy to find free copies of useful literature.
- throwaway31131 1y agoI'm not sure how "useful" or "good" the work is. But some one instruction computers have a considerable amount of tooling already in place. i.e. https://esolangs.org/wiki/FlipJump https://esolangs.org/wiki/FlipJump Flip Jump is amazing. I understand the theory and how it works but it still amazes me that it does. Things like this is why I love the science in computer science. And subleq even has a c-compiler and operating system, just wow. https://en.wikipedia.org/wiki/One-instruction_set_computer#Subtract_and_branch_if_less_than_or_equal_to_zero https://en.wikipedia.org/wiki/One-instruction_set_computer#S...
- spauldo 1y agoAny reason for ARM specifically? There are a lot of microcontrollers out there that fairly simple but without Intel's crustiness. Atmel, for instance. And if you decide to actually try experimenting with them you can get yourself set up for it for less than $100.
- throwaway31131 1y agohttps://shop.elsevier.com/books/computer-organization-and-design-arm-edition/patterson/978-0-12-801733-3 https://shop.elsevier.com/books/computer-organization-and-de... It's currently 50% off and not only will you learn ARM, and some history about ISAs in general, but you'll learn more about how the computer itself works. And if ARM isn't a hard requirement, an older edition that uses RISCV as the core ISA is a free download. https://www.cs.sfu.ca/~ashriram/Courses/CS295/assets/books/HandP_RISCV.pdf https://www.cs.sfu.ca/~ashriram/Courses/CS295/assets/books/H... Highly recommended.
- pmxi 1y agoThe first link was the textbook I used for my computer architecture course last semester and I concur. This was the first time our professor taught ARM instead of x86_64 because he believes ARM is the future.
- slashtom 1y agoI learned on the MIPS processor, computer organization / architecture one of the most challenging CS courses for me. I don't remember much but I definitely remember the mips pipeline...
- lauriewired 1y agoThis is my own channel, but I made a 10+ part series on modern ARM assembly you may find interesting. I used CPUlator for the demonstrations, which is a nice way to inspect the memory as well as the individual registers as you are running a program. All runs in the browser: https://youtube.com/playlist?list=PLn_It163He32Ujm-l_czgEBhbJjOUgFhg https://youtube.com/playlist?list=PLn_It163He32Ujm-l_czgEBhb...
- breckinloggins 1y agoThanks for your work on this. I’ve bookmarked several of these videos and used them as reference. Learning assembly with a really good visualizer or debugger in hand is highly underrated; just watching numbers move around as you run your code is more fun than it has any right to be. I really like Justine Tunney’s blinkenlights program. (https://justine.lol/blinkenlights/ https://justine.lol/blinkenlights/) A version of that for AArch64 / RISC-V would be really cool.
- WalterBright 1y agoI'm learning AArch64 assembly in the process of writing a code generator for it. godbolt.org is a great resource for "how do I do this?" Write a short function, run it through godbolt.org, see the instructions generated, lookup the instructions in the spec: https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.html https://www.scs.stanford.edu/~zyedidia/arm64/encodingindex.h... It'll be my keynote presentation at the D conference next month.
- Asm2D 1y agoI think AsmGrid has a great overview of X86 and AArch64 instructions: - https://asmjit.com/asmgrid/
- electroglyph 1y agowow, that's great. thanks for sharing!
- __alexander 1y agoI haven’t seen this site before. Thanks for sharing it.
- rfl890 1y agoFelix Cloutier's page has always been my go-to
- cylinder714 1y agohttps://www.felixcloutier.com/x86/ https://www.felixcloutier.com/x86/
- mananaysiempre 1y agoFor x86 encodings, there’s also http://ref.x86asm.net/index.html http://ref.x86asm.net/index.html and of course the venerable https://sandpile.org/ https://sandpile.org/.
- gnabgib 1y ago(2020) Discussion at the time (180 points, 38 comments) https://news.ycombinator.com/item?id=24195627 https://news.ycombinator.com/item?id=24195627
- nice_byte 1y agoAuthor here. The final part of this series is still sitting in my drafts. It was nominally supposed to be about flow control instructions, but as it goes with those things, it spiralled and ended up touching on relocations, position-independent code, aslr... One on these days I'll clean it up and post it
- 90s_dev 1y agoPlease do!
- deleted 1y ago[deleted]
- pm2222 1y ago>> Additionally, the higher 8 bits of rax, rbx, rcx and rdx can be referred to as ah, bh, ch and dh. Did you mean “ax, bx, cx, dx”?
- anamexis 1y agoThose would be the lower 8 bits, no?
- pm2222 1y agoax=ah:al eax=?:ax rax=?:eax
- grg0 1y agoIt's neither. al is the lower 8 bits of ax (ah the higher 8 bits). ax is the lower 16 bits of eax. eax the lower 32 bits of rax. Here's the AMD manual: https://docs.amd.com/v/u/en-US/40332-PUB_4.08 https://docs.amd.com/v/u/en-US/40332-PUB_4.08
- wunused 1y agoIn a 64 bit register, e.g., RAX, AL refers to the lowest 8 bits [0-7] and AH refers to the next 8 bits [8-15]. Together, AX refers to bits [0-15]. EAX refers to [0-31]. It's counterintuitive (or at least, inconsistent) that we have a name for bits [8-15] but not for [16-31] or [32-63]. My fuzzy understanding is that this came about from legacy decisions. This page has a helpful visualization at the top: https://www.cs.uaf.edu/2017/fall/cs301/lecture/09_11_registers.html https://www.cs.uaf.edu/2017/fall/cs301/lecture/09_11_registe...
- deleted 1y ago[deleted]
- ordu 1y agoax, bx, cx, dx are 16 bit registers referring to the lower 16 bits of rax, rbx, rcx, and rdx respectively. Bits 0..8 can be referred as al/bl/cl/dl, bits 8..16 as ah/bh/ch/dh.
- mixmastamyk 1y agoLet's learn RISC-V assembly! - https://en.wikipedia.org/wiki/RISC-V_assembly_language https://en.wikipedia.org/wiki/RISC-V_assembly_language - https://asm-docs.microagi.org/risc-v/riscv-asm.html https://asm-docs.microagi.org/risc-v/riscv-asm.html - https://riscv-programming.org/ https://riscv-programming.org/ - https://github.com/riscv-non-isa/riscv-asm-manual https://github.com/riscv-non-isa/riscv-asm-manual
- dapperdrake 1y agoAArch64/Arm64 assembly: https://mariokartwii.com/armv8/ch11.html https://mariokartwii.com/armv8/ch11.html
- urda 1y agoIt's always a great way to get a better understanding of things but at least just poking around assembly a bit once. You do not have to make a project or anything big, but do not be afraid to check it out.
- chasil 1y agoI would imagine that ARM1 would be more approachable than just about anything else. I understand that there were only 14 different instructions in the original design. "The 386 has about 140 different instructions, compared to a couple dozen in the ARM1 (depending how you count)." https://www.righto.com/2015/12/reverse-engineering-arm1-ancestor-of.html?m=1 https://www.righto.com/2015/12/reverse-engineering-arm1-ance...
- pjmlp 1y agoThankfully Intel syntax.
- Cockbrand 1y agoNow I'm curious - what other syntaxes are there?
- jabr 1y agoAT&T * https://imada.sdu.dk/u/kslarsen/dm546/Material/IntelnATT.htm https://imada.sdu.dk/u/kslarsen/dm546/Material/IntelnATT.htm * https://en.wikipedia.org/wiki/X86_assembly_language https://en.wikipedia.org/wiki/X86_assembly_language
- pjmlp 1y agoThe other one, is a clunky one from UNIX world point of view on x86 CPUs, follow the links on the sibling comment. Rather clunky and most UNIX Assemblers were never as powerfull as other systems macro assemblers, since after UNIX System V, it was there only as an additional external tool pass for the C compilation steps, and even before that, the assembler was quite minimalist. Then there is the whole brain twist of being used to op dest, src, and having to switch into op src, dest. I prefer the Intel approach as it is more similar to dest = src, rather than src -> dest. Intel's approach is also more common across various assembly languages.
- ykonstant 1y agoI think the schizophrenic notation 12(%ebp) is much worse than the dest/src switch.
- pjmlp 1y agoYes, that is the cherry on top, maybe.
- derdi 1y agodest/src order is not a big deal in absolute terms: The ISA designer picks an order, documents it, everyone follows their documentation, done. Intel picks one order for programming Intel, DEC picks another order for programming the VAX? Great, just look in the instruction set manual and you're set. The silly thing is importing one order to another architecture that uses the opposite order. Now your users have to transpose operands for no reason. The really silly thing is messing up the operand order of the cmp instruction in the process. The VAX assembly language had a compare with the sane operand order, BTW.
- vivzkestrel 1y agoSpectacular post, are you planning to add sections on reverse engineering executables because this definitely looks pretty close
- nice_byte 1y ago(i am the author) not to this series, but the very first post on the blog is an example of a simple reverse-engineering exercise: https://gpfault.net/posts/ripping-sprites-from-super-cyborg.txt.html https://gpfault.net/posts/ripping-sprites-from-super-cyborg....
- nayuki 1y agoI wrote one: https://www.nayuki.io/page/a-fundamental-introduction-to-x86-assembly-programming https://www.nayuki.io/page/a-fundamental-introduction-to-x86...
- Centrino 1y agoPlease provide a PDF version or make your page printable. Even when clicking your ad bar/banner down, a "print to PDF" in Chrome renders a crippled view with parts of the text covered, because of the remains of that ad bar/banner.
- masfuerte 1y agoThe print version is quite nice in Firefox with JS disabled.
- Cheyana 1y agoReally nice. Love the format, thanks!
- shikaan 1y agoSomething similar, but you can play with the examples in the browser without any local setup https://shikaan.github.io/assembly/x86/guide/2024/09/08/x86-64-introduction-hello.html https://shikaan.github.io/assembly/x86/guide/2024/09/08/x86-... For full disclosure, I am the author - apologies for the shameless plug
- LtdJorge 1y agoIt's cool. Do you sanitize the untrusted input? As far as I can see, it directly assembles with NASM and runs the binary.
- tialaramex 1y agoIt might be similar to Matt Godbolt's experience with his "Compiler Explorer". Most of your users are not trying to set fire to the free system, and when somebody does, on purpose or by accident, you focus on being able to reliably recover, not prevent it. So e.g. maybe Clara T Vandal "cleverly" seizes control of a random Compiler Explorer build box, well, that box is no longer marked OK because of her changes, it gets automatically torn down and replaced, no real problem. Did Clara do 0.001¢ of Bitcoin creation without paying for it? Yeah, maybe, and Clara probably cost Matt 0.1 cents for the data centre fees but it's not a big deal.
- norskeld 1y agoLooking at the source code of the code-editor [1], it seems to be embedding https://onecompiler.com https://onecompiler.com via the iframe and delegating code compilation and execution to it. So I guess it's a question to onecompiler, whether they sanitize input or not. :) [1]: https://github.com/shikaan/shikaan.github.io/blob/main/_includes/code-editor.html https://github.com/shikaan/shikaan.github.io/blob/main/_incl...
- shikaan 1y agoExactly this. I have been planning on trying to glue up something with v86[1] as I did in OSle[2] but I did not get to it yet. In that case, everything would run locally and sandboxes, so you would not have to care. [1]: https://github.com/copy/v86 https://github.com/copy/v86 [2]: https://github.com/shikaan/osle https://github.com/shikaan/osle
- fracus 1y agoI'd love to fool around in assembly but I can't think of anything interesting to do with it.
- raccomandoo 1y agoTIS-100 is a fun little game where you have a sort of pseudo-assembly and solve puzzles with it. I find it can help scratch that itch.
- archievillain 1y agoI would also recommend TIS-100's "sequel", Shenzhen I/O. TIS-100 is a bit 'dry', with the puzzles being entirely abstract. In SI/O, you roleplay as a developer emigrating to China for work, so all the puzzles are framed as real products you are developing for your company. One of the earlier puzzles, for example, is programming the equipment for a lasertag place.
- blashyrk 1y agoI second the Shenzhen I/O recommendation, because apart from only assembly programming, the game also has other constraints in the form of having to spacially arange various chips on a limited "enclosure" for the product you're building and connect them. It also rewards optimization both in terms of assembly and chip usage efficiency. Is a wonderful game, really.
- praptak 1y agoIt also has a really cool solitaire game-in-game as an... addition? Ornament?
- archievillain 1y agoI will reveal that I have played far more of Shenzhen solitaire than Shenzhen I/O itself. Zachtronics made a stand-alone version of the game[1], but there's also a fanmade version here: https://shenzhen-solitaire.tgratzer.com/ https://shenzhen-solitaire.tgratzer.com/ Which I find more enjoyable, both because it's online so it's easier to reach from anywhere, and also because I feel like the version of the solitaire inside the game is a bit... heavy feeling. Like there's some sort of input delay? Anyhow, I must have around 3000 completed games of solitaire across my devices. [1]https://store.steampowered.com/app/570490/SHENZHEN_SOLITAIRE/ https://store.steampowered.com/app/570490/SHENZHEN_SOLITAIRE...
- timonoko 1y agoI had quite entertaining session with ChatGPT and recursive fibonacci in nasm. We found out that C-version was twice as fast. So no returning back to year 1975. "Higher language version is easier to optimize, because machine gets better idea what you are aiming at." said Lex Fridman et al.
- danielscrubs 1y agoIve heard this for thirty years and it is as wrong now as it was then. Yes you need to be good at assembly (especially data oriented architecture), yes it takes forever, but that is no excuse to spew falsehoods.
- timonoko 1y agoWhat? Did I just give you an example that it is true? Natural language is the highest of course. We will return to assembly programming eventually, because those intermediate "highlevel" languages are not needed anymore between you and machine.
- nice_byte 1y agocorrect, understanding the instruction set architecture you are working with is required for reasoning about the performance of a given algorithm in detail. you will likely not be writing a lot of assembly by hand, however steering the compiler codegen in the right direction requires an understanding of what the compiler produces. even outside of enhancing performance, knowledge of instruction sets is instrumental for security research and reverse engineering. for some fun but practical demonstrations, see work by Nathan Baggs on YouTube - it involves staring at a lot of disassembly. i don't know where this misguided notion that assembly language is "1975" comes from. it's not like Cobol where a few large but important systems keep it alive. this is something that lies at the core of every interaction with computers that you have daily.
- pjmlp 1y agoWhy 1975, when high level programming exists since 1958? Also I should note that until early 1990's, C compilers were quite bad, that is why we wrote what would be now AAA games, in straight Assembly.
- specy 1y agoThought this was the perfect place to share a project I've been working on for a few years: https://asm-editor.specy.app https://asm-editor.specy.app It's an interactive online IDE for many assembly languages, currently M68K, MIPS, RISC-V and X86 (I need to improve X86). It has a ton of features that are made to teach assembly programming, and it can be embedded in other websites.
- ykonstant 1y agoFrom the profile picture I thought that was junferno for a second.
- fwsgonzo 1y agoI tried optimizing my CPU emulator dispatch in raw assembly to see if I could run a simple fibonacci program faster than C++. And I was not even close. In the end I merged it and made it a default-disabled dispatch option, because ... there has to be a way to make it faster! If you are daring, you can find my puny attempt here: https://github.com/libriscv/libriscv/blob/master/lib/libriscv/amd64/inaccurate_dispatch.nasm https://github.com/libriscv/libriscv/blob/master/lib/librisc... I did manage to improve it once I figured out some of the various modes of accessing memory, and I even managed to cut the jump table down from 64- to 32-bit which should help keep it in memory. I made the jump table part of .text in order to make it RIP-relative. For the fibonacci sequence program, not many bytecodes are needed. I would greatly appreciate some tips on what can be improved there.
- nice_byte 1y agohave you tried actually comparing what you have to what the c++ compiler generates? i don't have a lot of context here but I think it's possible that the difference is less due to the dispatch mechanism (i.e. how the next instruction is fetched) but due to the implementations of the instructions themselves. one opportunity for optimization is mapping emulated registers to real x86-64 registers and basically never spilling them to memory (so that way if you have to add you don't have to first fetch then add, but just add directly). though that makes writing the emulator a lot more annoying.
- secondcoming 1y ago> I made the jump table part of .text in order to make it RIP-relative Did you do this manually? gcc changed to put jump tables in .rodata always which causes problems when .rodata is stored in ROM. It does have the `-fno-jump-tables` option but that just disables jump tables rather than allowing you to control where they go.
- hollowonepl 1y agoI did not know that pointer indexing registers had direct low byte access, like `si/esi` (in 16/32bit when I last time used assemblers directly) that comes with `sil` as `ax/eax` analogy to `al`. Are there really opcodes for that that were added in the later evolution of x86_64? Seems I need to double check the specs of the platform again... out of plain curiosity!
- kruador 1y agoIt wasn't possible on the 386. Ken Shirriff discusses how the Intel 80386's register file was built at https://www.righto.com/2025/05/intel-386-register-circuitry.html?m=0 https://www.righto.com/2025/05/intel-386-register-circuitry..... Only four of the registers are built to allow 32-, 16- or 8-bit writes. Reads output the entire register onto the bus and the ALU does the appropriate masking. The twist is for the legacy 16-bit upper half-registers - themselves really a legacy of the 8080, and the requirement to be able to directly translate 8080 code opcode-for-opcode. The output of these has to be shifted down 8 bits to be in the right place for the ALU, then these bits have to be selected. AMD seem to have decided to regularise the instruction set for 64-bit long mode, making all the registers consistently able to operate as 64-bit, 32-bit, 16-bit, and 8-bit, using the lowest bits of each register. This only occurs if using a REX prefix, usually to select one of the 8 additional architectural registers added for 64-bit mode. To achieve this, the bits that are used to select the 'high' part of the legacy 8086 registers in 32- or 16-bit code (and when not using the REX prefix) are used instead to select the lowest 8 bits of the index and pointer registers. From the "Intel 64 and IA-32 Architectures Software Developer's Manual": "In 64-bit mode, there are limitations on accessing byte registers. An instruction cannot reference legacy high-bytes (for example: AH, BH, CH, DH) and one of the new byte registers at the same time (for example: the low byte of the RAX register). However, instructions may reference legacy low-bytes (for example: AL, BL, CL, or DL) and new byte registers at the same time (for example: the low byte of the R8 register, or RBP). The architecture enforces this limitation by changing high-byte references (AH, BH, CH, DH) to low byte references (BPL, SPL, DIL, SIL: the low 8 bits for RBP, RSP, RDI, and RSI) for instructions using a REX prefix." In 64-bit code there is very little reason at all to be using bits 15:8 of a longer register. This possibly puts another spin on Intel's desire to remove legacy 16- and 32-bit support (termed 'X86S'). It would remove the need to support AH, BH, CH and DH - and therefore some of the complex wiring from the register file to support the shifting. If that's what it currently does. Actually, looking at Agner Fog's optimisation tables (https://www.agner.org/optimize/instruction_tables.pdf https://www.agner.org/optimize/instruction_tables.pdf) it appears there is significant extra latency in using AH/BH/CH/DH, which suggests to me that the processor actually implements shifting into and out of the high byte using extra micro-ops.
- anthk 1y agoI remember a book on amd64 assembly which used GNU/Linux and NASM as the base. It has exercises to follow your progress: http://www.egr.unlv.edu/~ed/assembly64.pdf http://www.egr.unlv.edu/~ed/assembly64.pdf
- angelmm 1y agoThis is the kind of introduction I was looking for! I'm currently learning a bit more about this instruction set, so that's perfect. Also, there are so many great resources in the comments.
- johnisgood 1y agoFor FASM, I really like https://flatassembler.net/docs.php?article=manual https://flatassembler.net/docs.php?article=manual. There are a couple of great books out there as well that I have used. I cannot recall their names right now. :(
- Run_DOS_Run 1y agoGreat opportunity to share an older project: https://www.AssemblyArena.com https://www.AssemblyArena.com - an educational game for people who would like to learn and/or program in assembly. It's a (non mobile-optimized) web-based PvP assembly programming game. The syntax is highly inspired by x86 assembly and the game itself by Core War. There is also a small tutorial and a ranked ladder powered by Glicko-2. Source Code: https://github.com/m2w4/assembly-arena https://github.com/m2w4/assembly-arena
- elzbardico 1y agoThis article made me realize that, at my home, out of 7 full-fledged computers, that is, notebooks, servers or desktops, there's not a single X86 machine. Maybe there are a couple old dell notebooks somewhere in the garage, but I am not even sure they still boot.
- kevstev 1y agoThe silent and really unheralded disappearance of Wintel from my home surprised me a few weeks ago as well. It wasn't a conscious decision, they just got slowly replaced by macbooks, and an ARM based NAS... etc. Kind of like how I also realized I no longer have an optical disc reader... despite still having spindles of very old stuff.
- elzbardico 1y agoAnd this is kind of sad in the context of this post. Because I have always wanted to dive deeper into assembly, and there are loads of material to study X86 assembly out there. But being able to run it only in a virtual machine, it is a little bit demotivating. Well, there are some chinese folks selling newly built PC-XT compatible machines on the internet. Maybe I could go this way. And probably, pure, original 8086 assembly is a lot more fun than overly complicated X86_64 with lots of extensions.
- emeraldd 1y agoThere's always arm assembly. It's a differen ISA of course, but a lot of the concepts transfer pretty nicely. You could also look at something like the Zimaboard or similar machines.
- gtirloni 1y agoIf you just want to learn for the fun of it, check out RISC-V instead. It might give you that early days feeling.
- kevstev 1y agoI found using qemu to be quite simple and pretty decent. I guess it depends on what you are looking to do- really low level bootloader/OS type stuff or actually explore the instruction set and maybe build something useful. Learning about the BIOS interface was actually quite enlightening, but in general ARM and RISC-V is much less complex.