3 ms·
Studying the x86 architecture is kind of like studying languages with lots of irregularities and vestigial bits, and with competing grammatical paradigms, e.g.
by trealira 2y ago
Studying the x86 architecture is kind of like studying languages with lots of irregularities and vestigial bits, and with competing grammatical paradigms, e.g. French. Other architectures, like RISC-V and ARMv8, are much more consistent.
- x0x0 2y agoI think English may be a better example; we just stapled chunks of vulgar latin to an inconsistently simplified proto-germanic and then borrowed words from every language we met along the way. Add in 44 sounds serialized to the page with 26 letters and tada!
- WalterBright 2y agoThe Norman conquest of England means English is a language with barbarian syntax and French nouns. It's a happy mess of cultural appropriation! Squeezing the lot into 26 characters was simply genius - enabling printing with movable type, Morse code, Baudot code, ASCII, etc. Of course, then icons came along and ruined everything.
- aengelke 2y ago> Other architectures, like [...] ARMv8, are much more consistent. From an instruction/operation perspective, AArch64 is more clean. However, from an instruction operand and encoding perspective, AArch64 is a lot less consistent than x86. Consider the different operand types: on x86, there are a dozen register types, immediate (8/16/32/64 bits), and memory operands (always the same layout). On AArch64, there's: GP regs, incremented GP reg (MOPS extension), extended GP reg (e.g., SXTB), shifted GP reg, stack pointer, FP reg, vector register, vector register element, vector register table, vector register table element, a dozen types of memory operands, conditions, and a dozen types of immediate encodings (including the fascinating and very useful, but also very non-trivial encoding of logical immediates [1]). AArch64 also has some register constraints: some vector operations can only encode register 0-15 or 0-7; not to mention SVE with it's "movprfx" prefix instruction that is only valid in front of a few selected instructions. [1]: https://github.com/aengelke/disarm/blob/master/encode.c#L19-L54 https://github.com/aengelke/disarm/blob/master/encode.c#L19-...
- trealira 2y agoAdmittedly, I never wrote an assembler, but the encoding of x86-64 seems pretty convoluted [0] [1], with much of the information smeared across the some bits in the Mod/RM and SIB bytes and then extended by prefix bytes. It's more complicated than you would assume from having only written assembly in text and then having the assembler encode the instructions. One of the things that sticks out to me is that on x86-64, operations on 32-bit registers implicitly zero out the upper 32-bits of the corresponding 64-bit register (e.g. "MOV EAX, EBX" also zeroes out the upper 32-bits of RAX), except for the opcode 0x90, which, logically, would be the accumulator encoding of "XCHG EAX, EAX" but is special-cased to do nothing because it's the traditional NOP instruction for x86. So you have to use the other encoding, 87 C0. The fact that AArch64 has instructions that are almost always 4 bytes, and the fact that they clearly thought out their instruction set more (e.g. instead of having CMP, they just use SUBS (subtract and store condition codes) and store the result in the zero register, which is always zero), is what made me say that it seemed more regular. I hadn't studied it in as close detail as x86-64, though. But, you've written an an ARM disassembler and I haven't; you seem to know more about it than me, and so I believe what you're saying. > AArch64 also has some register constraints x86-64 also has some, in that many instructions can't encode the upper 8 bits of a 16-bit register (AH, BH, DH, CH) if a REX prefix is used. [0]: https://wiki.osdev.org/X86-64_Instruction_Encoding https://wiki.osdev.org/X86-64_Instruction_Encoding [1]: http://www.c-jump.com/CIS77/CPU/x86/lecture.html http://www.c-jump.com/CIS77/CPU/x86/lecture.html
- WalterBright 2y ago> you've written an an ARM disassembler Here's my AArch64 disassembler work in progress: https://github.com/dlang/dmd/blob/master/compiler/src/dmd/backend/arm/disasmarm.d https://github.com/dlang/dmd/blob/master/compiler/src/dmd/ba... I add to it in tandem with writing the code generator. It helps flush out bugs in both by doing this. I.e. generate the instruction, the disassemble it and compare with what I thought it should be. It's quite a bit more complicated than the corresponding x86 disassembler: https://github.com/dlang/dmd/blob/master/compiler/src/dmd/backend/x86/disasm86.d https://github.com/dlang/dmd/blob/master/compiler/src/dmd/ba...
- 2y ago