6 ms·
The Art of 64-bit Assembly
- Retr0id 2mo ago> what Windows actually expects the vtable to look like I'm not a Windows-knower, are vtable layouts part of the user<->kernel ABI?
- invokestatic 2mo agoIt’s part of the MSVC x64 ABI, not a part of the kernel ABI. The kernel and user mode (Win32) APIs all use C linkage so vtables are not relevant and the ABI is a convention of the compiler not the OS. Practically speaking though if your software runs on Windows it will probably use the MSVC ABI.
- Joker_vD 2mo agoLast time I checked, software compiled with both Cygwin and MSYS2 internally uses SysV calling convention, only switching to WINAPI when calling, well, Win32 API.
- okanat 2mo agoIt is more complicated than that. MSYS2 isn't just Cygwin. It has different environments. MSYS environment is just Cygwin and it uses Itanium IIRC for C and C++ non-Win32 calls since it emulates POSIX. If it links with Windows C runtime they use __cdecl. Win32 API calls always use __stdcall convention / ABI. However, Mingw environments (Mingw64, UCRT, CLANG etc.) are intended for native Windows development, hence, they use normal MSVC __cdecl ABI for C library calls and internal function calls too. Win32 calls are again __stdcall. Unlike C, for C++ all MSYS environments use Itanium ABI since they link with GNU libstdc++ or Clang libc++. I think it is possible to use MSVC C++ ABI with Clang but it could be complicated since it requires recompilation of at least libc++.
- Joker_vD 2mo agoTL;DR: You can mix and match calling conventions as long as you actually track what piece of (compiled) software uses what convention.
- boguscoder 2mo agoYes, you either follow Itanium ABI (non Win) or MSVC ABI. Technically nothing stops _your_ compiler from implementing totally own conventions but it will only be compatible with itself
- Joker_vD 2mo agoGHC uses its own calling convention yet it's compatible with Win API just fine. The secret, of course, is to implement not only your bespoke calling convention, but also the other ones that you care to interoperate with.
- jcranmer 2mo agoAll of the major kernel ABIs are using C function interfaces as their stable ABI (except Linux, which uses an assembly syscall instruction as the stable interface, although you still rely on a lot of the ancillary C ABI for things like struct layout or stack layout). For C++ ABIs, there are really only 2.5 major ABIs: the MSVC ABI, used by MSVC and clang wanting to be compatible with MSVC, and the Itanium ABI, used for everything else. There are some slight variants on the Itanium ABI which makes the ".5": ARM uses a different layout for exception handling tables, and there are some flags you can set to use a more compressed vtable layout (32-bit offsets instead of 64-bit pointers). (There are other older ABIs, but either companies stopped making a C++ compiler or they switched to Itanium.) Windows COM APIs (which isn't part of the kernel, they're still userspace libraries) rely on an IDL which is meant to be directly compatible with the C++ vtable. That said, they also use a restricted subset of C++ that all of the ABIs are going to agree on for vtable layout--if you don't overload any functions, and you don't have any virtual inheritance, there's pretty much only one possible sane vtable layout, and everyone does that.
- masfuerte 2mo agoBeing pedantic, the COM vtable layout is defined independently of C++. The Windows headers used to (and maybe still do) have macros that could declare COM vtables as explicit structs so you could use Windows COM interfaces from C. That used to be the case anyway. It's possible they binned the C support in the switch to 64-bit. I haven't looked since.
- wasmperson 2mo agoYes the support is still there, although official MS documentation no longer mentions it. Some of those headers rather flagrantly violate C's strict aliasing rules, which I suspect is the reason MSVC never implemented type-based aliasing optimizations.
- rramadass 2mo agoCOM is still a language-independent binary standard. The first three entries in the vtable must always be IUnknown methods and all methods must use __stdcall calling convention. The Layout of a COM Object by Raymond Chen - https://devblogs.microsoft.com/oldnewthing/20040205-00/?p=40733 https://devblogs.microsoft.com/oldnewthing/20040205-00/?p=40...
- rramadass 2mo agoThoroughly Understanding C++ ABI - https://news.ycombinator.com/item?id=49145259 https://news.ycombinator.com/item?id=49145259
- EtienneDeLyon 2mo ago[dead]
- amelius 2mo agoIs anyone still writing assembly in the age of LLMs? Asking seriously because most assembly is just doing one very simple thing very fast and because it's so simple conceptually, an LLM can easily code it without errors.
- WalterBright 2mo agoI do now and then, for bits of code that is not expressible in the language. Things like special instructions, or special fixups.
- sousousou 2mo agoYep. In my experience, LLMs easily go in circles with even simple assembly, creating fixes that result in 2x slower code and then fixing those with even slower code. They are pretty great as a reference or finding needle in the haystack bugs though!
- ndesaulniers 2mo agoI was able to use Claude to translate a few thousand lines of assembler from one syntax+toolchain to another. Process was definitely iterative; had to keep adding a few rules along the lines of "don't do this...here's the equivalent pattern." But in the end it did a good job and saved me a ton of time. Allowed me to move a ton of unit tests off a hand rolled broken+bad assembler to a modern production toolchain.
- derefr 2mo agoIs that with or without the LLM being able to assemble + profile its hypotheses itself? Because “optimize this code to execute in fewer CPU cycles under the test harness” seems like one of those perfect self-contained problems for LLMs (their equivalent of an “embarrassingly parallel problem”: an “embarrassingly-easily-explored solution space with embarrassingly-easily-measured objective success criteria.”) Sure, they might make all sorts of dumb hypotheses at first, but as long as the results of those stay in their context, they do seem to eventually “run out of ways to be stupid.” (Which is to say, LLMs seem to experience in-context learning even via self-directed trial-and-error, if given a sufficiently-large number of iterations and no way to cheat.)
- tensegrist 2mo agoi'm sorry, starting with "you can ask AI to … [but it'll do an incomplete and bad job]" and then launching forth into a hundred words of AI-produced text is not very appetizing i hope this is the publisher's fault and the author replaces it with something decent of their own. contrary to the opinions i've heard around (including elsewhere on this thread) learning asm is still meaningful today and it's something i'd like to get better at so i will consider getting this book or one like it once $work is a bit less hectic
- asibahi 2mo agoThis text doesn’t seem AI generated to me.
- boondongle 2mo agoWe've really gotten to the point that certain styles seem AI generated in many cases because many folks are poor writers and anything past a high school level is difficult for them. I'm not speaking in this case specifically, just in general. It's also one of the reasons its insanely popular in ESL countries and frustrating/disliked in English-speaking countries because it makes things easier in one and harder in the other. It was never the goal, but it is the reality. The same style people call AI, was often called being a pedant or being wordy 10 years ago.
- asibahi 2mo agoThis publisher copy is neither pedantic nor wordy. It is just a market blurb for the book. The thing that frustrates me the most about AI is how every thread in every forum spend half the time arguing whether an article is AI or not, as if bad writing only started to exist with AI. Just fucking don't read it.
- tanseydavid 2mo agoIt does not even have to be slop, the compulsion to call out AI-involvement in writing is out of control, esp. on HN. Em-dashes as the signal is the most-upsetting for me. I have been using them properly and frequently for decades. Slop is slop. If it is AI-slop then fine, go ahead and call it out.
- csense 2mo agoI'm sorry, MASM? All the cool kids use NASM or YASM.
- mdp2021 2mo agoSome still like FASM. Why NASM or YASM?
- sureglymop 2mo agoI prefer FASM but NASM is a strong second choice. But at the end of the day it really doesn't matter.. purely preference.
- sitzkrieg 2mo agofasm absolutely rules on windows
- anta40 2mo agoSince NASM/YASM is written in C, it's more portable. On my ARM Mac, NASM works fine. FASM is cool (and still being development), but since it's written in 32-bit x86 asm, let's just say macOS is a 2nd class citizen.
- ndesaulniers 2mo agoThe Linux kernel prefers GAS (or clang) w/ the C preprocessor. Luckily most of clang's assembler unit tests (and LLVM's MC layer unit tests) also use GAS style syntax.
- rurban 2mo agoBecause the Intel syntax is limited, and pretty broken by binutils. I had to change my C compiler rcc to emit AT&T GAS, instead of Intel syntax, even if Intel syntax looks easier on the eye. GNU Assembler (GAS) ≥2.45 on x86-64: call and jmp to global labels in Intel syntax cause operand type mismatch errors. RCC emits .intel_syntax noprefix by default, but GAS ≥2.45 rejects direct branches to global symbols in this mode. Local labels (.L.xxx) work fine. Tests with user-defined function calls (bitops-1, fprintf-1, etc.) may fail to assemble under these versions. Root cause: rcc emits lea r11, [rip + sI] but GAS requires AT&T sI(%rip) for globals.
- rajeevk 2mo ago>> You can ask an AI to explain how vtables work in x86. It will give you something that sounds right. What it won’t give you is what Windows actually expects the vtable to look like, why method dispatch behaves the way it does at the instruction level, or what breaks when you deviate from convention. This volume of The Art of 64-Bit Assembly closes the gap between a plausible explanation and genuine understanding. Once LLMs are trained with the content of this book, then this statement will no longer be true. If this book becomes even a bit popular, these LLMs will get access for sure to the content of this book in their next training.
- jagged-chisel 2mo agoBut will they prioritize this information over what they have currently, or over their own hallucinations?
- mdp2021 2mo ago> Once LLMs are trained with the content of this book I strongly believe that the "future" should be LLM+Corpus - something beyond LoRA or RAG or context, but what we need and will have will be a generally strong LLM augmented with the most proper learning from the "selected library of relevant material". And in parallel, also the reasoner over the corpus will be implemented (something that properly studies, not just reads, and achieves the pinnacle of reflection over the corpus).
- f3abfeca54812 2mo agoAre you saying that people should then write books for LLMs only so that you can query them to get the summarized answer and not pay for the book?
- mdp2021 2mo agoI cannot get a faint idea about how you managed to get such a twisted misunderstanding. Let us reformulate through the framework: the learned wrote books; the learners read them books, as many as possible in a ranked list; we may one day achieve automated learners; learned learners are our consultants; we benefit from the level of learning of them consultants; we would benefit greatly from the Perfected Learner; I gave a few lines of the general directions towards "thinking of them in view of building them" in the post above...
- Someone 2mo agoWeird title for a book on assembly - for x64 - on Windows - using MASM There are other 64-bit OSes, CPUs and assemblers for them, and people do use them.
- Retr0id 2mo agoIf you're actually writing software in assembly (as opposed to merely optimizing hot functions in an otherwise high-level codebase), in my experience MASM is the most pleasant tool for the job.
- b5n 2mo agoThe most pleasant is the one you're most familiar with. I still use gas with at&t syntax.
- adrian_b 2mo agoMASM was a decent assembler, but it also had some syntax choices that lead to excessive verbosity. In any case, today nasm is mostly equivalent with it, if not better, while being kept much more up-to-date with the Intel-AMD ISA extensions.
- not_a9 2mo agoOut of idle curiosity: can NASM emit Windows unwind information? For the matter, can any assembler do so automatically?
- norir 2mo agoIf you need better performance than a higher level language affords you, I would not recommend programming directly in asm. Instead, I would write a compiler. Raw asm is seductive since the start up cost is relatively low. You can get started in an afternoon. The trouble is that writing correct assembly is much harder than high level code. You have to hold in your head the register state at all times. You have to know if the function you are calling will clobber registers that you need after the call and manually save/restore them. This will slow down your velocity and the resulting code will be long and difficult to read. It will also rely on a lot of undocumented information that only resided in your head while writing and has since been evicted. Good luck debugging a program written in assembly that no one has looked at for two months. On the other hand, if you write your own non optimizing compiler, you can avoid a lot of these problems by, for example, tracking what registers a function writes and ensuring they are saved before a call and restored after. Then you can actually get the raw performance of handwritten asm without the pitfalls (the resulting code would still he harder to read and maintain than equivalent high level code, but at least it would be tractable). Even better, you can write your own high level assembler that is actually portable to other architectures. For example, instead of directly modeling x86_64, your compiler can model a cpu with 16 general purpose registers and a set of instructions that map to x86_64 instructions. An arm port would be straightforward since arm also has 16 general purpose registers and you can model x86_64 instructions as one or more arm instructions (and you have extra registers for x86_64 instructions that must be modeled as multiple arm instructions). Or you could do the reverse and model 32 general purpose registers using arm instructions and use predefined memory slots as virtual registers on x86_64.
- sylware 2mo agoI am more curious about how they would cleanly manage hierarchical labels (usually called "namespaces"), register naming, and stack management with deep register spilling, description of the register state on the various entries from the various dominators of a code block. I am doing all that with a basic C pre-processor in my assembly source code. But the more I think about this, the more I think I should write my own pre-processor, which "should" be much simpler than a C pre-processor in the end and would do a cleaner job since taylored for those usages (the "annoying" thing is the arithmetics expression evaluation). I would write this pre-processor in assembly, namely design a binary specification (that to be ready for other ISA implementations). Then, they are the really important things: for all micro-architectures, how to be friendly to conditional branch predicition, how to handle BTB entries layout in a cache line, show how important the "cache line" is ubiquitous, etc. I remember clearly one of the TheHeavyThing developers telling me than with a basic and naive hand compilation of gzip, he was beating the best compilers, at that time, by a consistent 10/15%. Let me remind people here of something: nobody is supposed to be able to beat a compiler on deep and hairy compilation units. If it is the case, something is wrong in that compiler.
- slashdave 2mo agoI'm... confused. Don't we use macro assemblers anymore?
- sureglymop 2mo agoWe do. I always use fasmg and it's amazing!!
- sylware 2mo agofasmg[12] is much more powerful than gas or nasm(~yasm): it is not a classic pre-processor. With CALM, it is basically a language able to implement assemblers supporting various binary file formats.
- sylware 2mo agoThe pre-processor of an assembler is specific to that very assembler. For instance, with a C pre-processor, I have a very lean C pre-processor dialect which allows me to assemble simple x86_64 code with... fasmg[12] or nasm(probably yasm) or gas(intel syntax). A big project which was bitten by specific pre-processor abuse: ffmpeg with nasm (but it is still much less toxic than to start to be hard dependent on advanced and specific C compiler extensions... look a the failure from linux on that matter).
- rramadass 2mo agoRelated; 1) All Assembly/C++ books by Daniel Kusswurm. 2) Low-level Programming: C, Assembly, and Program Execution on Intel 64 Architecture by Igor Zhirkov.
- rramadass 2mo ago3) x86-64 Assembly Language Programming with Ubuntu by Ed Jorgensen - https://open.umn.edu/opentextbooks/textbooks/x86-64-assembly-language-programming-with-ubuntu https://open.umn.edu/opentextbooks/textbooks/x86-64-assembly...
- woadwarrior01 2mo agoWow, I can't believe that the author is still updating the book! I'd learnt protected mode assembly from an older version of this book, decades ago. And IIRC, there was an even older 16-bit version of the book back then.
- skippyfish 2mo agoI know that we're discouraged from meta-comments, but what is going on in this thread? It's a nearly 800-page book about the art of programming. A huge amount of work on a topic that should be dear to our hearts. News for hackers, right? But somehow, the discussion has three themes. It's 50+ comments of "I don't like the first sentence of the marketing copy", "I don't like the tool the author is using", and "what would happen if we train an LLM on this book?". Has anyone read the sample chapter? Did you like it? Anyone here owns volume 1 and has opinions about that?
- roundwego 2mo ago[flagged]
- mathisfun123 2mo agothis is what almost every hn post is: lowbrow reflexive/reactionary responses. it's been like this for years. try to call it out and you'll be censured by dang or one of the other police officers for being "uncharitable" or something like that <shrug>
- yesitcan 2mo ago[flagged]
- ternaryoperator 2mo agoReally? I have quite the opposite impression. HN is one of the few places I can come to where intelligent conversations can be found. Sure, sometimes discussions run off the rails into the weeds, but snark is rare, and when conversations stay on track, they often add significantly to the post.
- lexicality 2mo agoI own volume 1 and when it first arrived I dropped it on my foot and had to go to the doctor. I have not got around to reading it again. His original x86 ASM book was good though. I also read his Write Great Code series and generally found it to have some pretty good advice, but it was also full of things like recommendations to never trust compilers and to write lots of arcane unreadable magic code to unlock ultimate speedy hacker cred. That being said, if you want to learn about ASM in TYOOL 2026 then you could do a lot worse than learning it from someone who doesn't trust compilers and does everything themselves.
- MaskRay 2mo agoInteresting to see that people are still spending much time on assembly languages :) I've had a lot of fun with it in recent years as well. (Shameless plug: I've written a few on LLVM integrated assembler regarding better fragments and improving expressions and relocations). When comparing GNU Assembler and MASM, GAS is missing many features: while loop, string processing (.e.g strlen) > page 3: "It’s important to understand that MASM converts macro invocation arguments to text values before doing the macro expansion" Like MASM, GAS uses call-by-name evaluation by default. While GAS's altmacro mode does allow for expression evaluation using syntax like `%(1+2)`, it has strict limitations: it only supports absolute expressions and is restricted to argument positions. In contrast, MASM's % operator (page 8) looks far more general.
- adrian_b 2mo agoThe GNU assembler is not intended to be used by humans, but its goal is to assemble the output of compilers. On Linux, the "standard" assembler for humans is "nasm", though there are also others. For anyone writing a non-negligible amount of code in an assembly language it is essential to develop or get from elsewhere a comprehensive library of macros, for avoiding to write huge amounts of boilerplate.
- pjmlp 2mo agoThat is true of all UNIX assemblers, they never had the "used by humans" culture, rather being part of a C compiler pipeline approach. At least since UNIX v4. All good Assemblers have come from Amiga, Atari, PC world.
- climate_denier_ 2mo agoGreat, follow up with The Art of 64-bit Assembly for PowerISA
- iamcreasy 2mo agoI built compiler that compiles to 16bit x86 via MASM. This books feel like a natural next step, but I was wondering if there is a linux equivalent book I can choose instead?
- deleted 2mo ago[deleted]
- yotsubaNishiki 2mo agoI'm just gonna be the weirdo in this comment thread and say: yay! Assembly! The most god forsaken language i ever had to learn. But still very very useful
- toplinesoftsys 2mo agoWe need books like that now more than ever. AI makes us lazy, forgetting how it works "under the hood". We should be curious and keep asking questions, or we will not be able to understand all this geneated AI code slope.
- lowbloodsugar 2mo agoI don’t get it. I am this books target market. Part of this demographic is that if you challenge me, I will accept the challenge. So challenging me to figure out how to do this by using AI instead of buying this book seems like a serious fail.
- hollowonepl 2mo agoNice, I did not know author wrote so many different books about assembly coding.