4 ms·
Yes, the simple opcodes are the most-used, and this was one of the ideas floating around that helped inspire RISC, but be careful how you figure out which opcod
by msla 4y ago
Yes, the simple opcodes are the most-used, and this was one of the ideas floating around that helped inspire RISC, but be careful how you figure out which opcodes are different. For example, mov in x86 is extremely polysemous: It can be move from register to register, load register with data from RAM, store register contents out to RAM, store a constant out to RAM, and even perform ALU operations and then use the result of those operations as a memory address for storing something out to RAM. On a cleaner (RISCier) ISA, all of those would be different opcodes or sequences of opcodes, assuming they're possible at all.
Other than that, this piece looks good as far as it goes.
- kasajian 4y agohttps://github.com/xoreaxeaxeax/movfuscator https://github.com/xoreaxeaxeax/movfuscator
- jcranmer 4y agoOne thing worth pointing out is that, if you ignore the way the assembly is written and instead look at the binary encoding, then x86 is closer to a RISC idea. Essentially, the core of an x86 instruction is opcode + ModR/M byte, which encodes a register and register-or-memory operand. There's one opcode [1] that means "move from second operand to first operand" and a different opcode that means "move from first operand to second operand". Intel merely decided to call both of these instructions "MOV" rather than "LD" and "ST"--but it does basically have them. There's also another opcode that loads immediates into a register. Furthermore, the ability to put a memory operand on, say, an ADD instruction is close in effect to having a compressed instruction encoding that encodes "LD to a temporary, unnamed register followed by ADD that register to the destination register" in fewer bytes than having both (also avoids clobbering a register, useful given the thin 8 registers 32-bit x86 has). [1] Okay, several, to vary the operand size (8-bit, 16-bit, 32-bit, 64-bit).
- msla 4y ago> One thing worth pointing out is that, if you ignore the way the assembly is written and instead look at the binary encoding, then x86 is closer to a RISC idea. Essentially, the core of an x86 instruction is opcode + ModR/M byte, which encodes a register and register-or-memory operand. You could say the same thing about the VAX, which was even more CISC than the x86 is, because of how its opcode encoding worked: Bytes for the opcode, bytes for addressing modes, bytes for register specifications or constant values or memory addresses. Ditto the PDP-10. Which is to say that's not a helpful way of making the RISC/CISC divide because it ignores everything that makes those kinds of processors different. Somewhat down in this page, written by processor designer John Mashey, is a list of features which RISC processors tend to have that CISC processors don't: https://userpages.umbc.edu/~vijay/mashey.on.risc.html https://userpages.umbc.edu/~vijay/mashey.on.risc.html Above that list are two points which get to the heart of the RISC project: > The RISC characteristics: > a) Are aimed at more performance from current compiler technology (i.e., enough registers). > OR > b) Are aimed at fast pipelining > - in a virtual-memory environment > - with the ability to still survive exceptions > - without inextricably increasing the number of gate delays (notice that I say gate delays, NOT just how many gates). The point b is where RISC chips really pulled away from CISC in terms of architectural design, especially chips like the MIPS, which Mashey worked on: The MIPS had a number of points where it exposed the tricks it used to pipeline more aggressively, even at the expense of making compilers somewhat harder to write and/or human assembly-language programmers think a bit harder. However, the lack of complicated addressing modes (post-increment, scale-and-offset, etc.) and the lack of register-memory opcodes with ALU operations, and total lack of memory-memory operations, is still a very common feature of RISC design. I also want to take on this: > Furthermore, the ability to put a memory operand on, say, an ADD instruction is close in effect to having a compressed instruction encoding that encodes "LD to a temporary, unnamed register followed by ADD that register to the destination register" in fewer bytes than having both (also avoids clobbering a register, useful given the thin 8 registers 32-bit x86 has). The difference between having one opcode which does both memory operations and ALU operations and not having those kinds of opcodes is faulting: If the CPU has to take a fault, does it have to back out a lot of ALU state such that opcodes appear to be atomic? CISC chips do, and they pay for it, whereas RISC chips are designed not to have to. This, again, makes pipelining easier. (And the page I linked to goes into this as well.) CISC/RISC is points on a scale, but that doesn't mean it's helpful to "reinterpret" things to try and make CISC seem equivalent to RISC.
- zokier 4y agoOne of my pet ideas is to design a new set of mnemonics and syntax for x64 assembly, the Intel ones are pretty crufty in many ways and imho have potential to be improved. Of course it will not win any popularity contests, but could be interesting design exercise.
- timmisiak 4y agoThe target audience here were folks that have very little experience with asm, but you're completely right that a lot of complexity gets glossed over. That's not even to mention cases where an instruction behaves differently depending on the code segment attribute or privilege level it's running in.