Disassembly of binary code is hard, but necessary for improving the security of binary software. Over the past few decades, research in binary disassembly has produced many tools and frameworks, which have been made available to researchers and security professionals. These tools employ a variety of strategies that grant them different characteristics. The lack of systematization, however, impedes new research in the area and makes selecting the right tool hard, as we do not understand the strengths and weaknesses of existing tools. In this paper, we systematize binary disassembly through the study of nine popular, open-source tools. We couple the manual examination of their code bases with the most comprehensive experimental evaluation (thus far) using 3,788 binaries. Our study yields a comprehensive description and organization of strategies for disassembly, classifying them as either algorithm or else heuristic. Meanwhile, we measure and report the impact of individual algorithms on the results of each tool. We find that while principled algorithms are used by all tools, they still heavily rely on heuristics to increase code coverage. Depending on the heuristics used, different coverage-vs-correctness trade-offs come in play, leading to tools with different strengths and weaknesses. We envision that these findings will help users pick the right tool and assist researchers in improving binary disassembly. TABLE III: The specifics of existing algorithms (numbered with rings like ) and heuristics (numbered with discs like ). Alg. Algorithms & Heuristics Goals Tools Disassembly Linear Sweep 1 Start from code addresses with symbols Code accuracy OBJDUMP, PSI, UROBOROS 1 Continuous scanning for instructions Code coverage OBJDUMP, PSI, UROBOROS 2 Skip bad opcodes Code accuracy OBJDUMP 3 Replace padding and re-disassembly Code accuracy PSI 4 Exclude code around errors Code accuracy UROBOROS Recursive Descent 2 Follow control flow to do disassembly Code accuracy DYNINST, GHIDRA, ANGR, BAP, RADARE2 3 Start from program entry, main, and symbols Code accuracy DYNINST, GHIDRA, ANGR, BAP, RADARE2 5 Function entry matching Code coverage DYNINST, GHIDRA, ANGR, BAP, RADARE2 6 Linear sweep code gaps Code coverage ANGR 7 Disassembly from targets of xrefs Code coverage GHIDRA, RADARE2 Symbolization Xrefs 4 Exclude data units that are floating points Xref accuracy ANGR 8 Brute force operands and data units Xref coverage UROBOROS, MCSEMA, GHIDRA, ANGR 9 Pointers in data have machine size Xref accuracy UROBOROS, MCSEMA, GHIDRA, ANGR 10 Alignment of pointers in data Xref accuracy UROBOROS, MCSEMA, GHIDRA 11 Pointers in data or referenced by other xrefs can be non-aligned Xref coverage GHIDRA, ANGR 12 References to code can only point to function entries Xref accuracy GHIDRA 13 Enlarge boundaries of data regions Xref coverage GHIDRA, ANGR 14 Address tables have minimal size of 2 Xref accuracy GHIDRA 15 Exclude pointers that may overlap with a string Xref accuracy MCSEMA, GHIDRA 16 While scanning data regions, use step-length based on ...