3 ms·
Do you know if NOP is really executed as `XCHG AX, AX` (as would be implied from its position in the opcode map and its cycle count) or if it is special-cased i
by abbeyj 6y ago
Do you know if NOP is really executed as `XCHG AX, AX` (as would be implied from its position in the opcode map and its cycle count) or if it is special-cased in some way?
I've always been curious about the XLAT instruction. It performs an operation like `MOV AL, [BX + AL]` (if that were a valid instruction). I assume this instruction was designed to do EBCDIC <-> ASCII conversions using a simple loop consisting of `LODSB / XLAT / STOSB` which would explain why the input and output are both hardcoded to AL. But it seems like it would have been fairly easy to allow the programmer to specify different register(s) and the instruction probably would have been a lot more useful generally if that was allowed.
It is the only place in the ISA that I know of where an 8-bit value is zero-extended to 16 bits before being added to another value. Short jumps use a sign-extended 8-bit value (and are a special case anyway since they deal with the instruction pointer). Other additions are always 8+8 or 16+16. Is there some special case in the processor to allow just AL to be zero-extended in this way? If so, that would go some way toward explaining why this instruction isn't more flexible. I realize this may be very difficult to determine working from a die photo, at least without completely reverse engineering the entire microcode ROM.
- kens 6y agoYes, NOP is just an XCHG AX, AX. For instructions such as XCHG, the microcode doesn't know anything about the specific registers; hardcoded circuitry substitutes the registers from the instruction. This saves on microcode size. Microcode also doesn't know about 8-bit vs 16-bit instructions; that is also done in circuitry. As far as XLAT, I haven't seen anything yet to answer your question. I hope to figure out the microcode, which should provide more details.
- raphlinus 6y agoOne theory on XLAT is that it's there to make it easier to adapt code originally written for 6502, where the "indirect indexed" addressing mode was popular. The zero-extended 8 + 16 addition is the same, and this would otherwise require a sequence. For example, to do code page translation on 6502 you'd definitely use indirect indexed at the core. But yeah, this is an oddball instruction, one of the most non-RISC-like in the set.
- kiwidrew 6y agoThe 8086/88 does in fact execute 90h (the NOP opcode) as XCHG AX, AX. It does not generate any change in the user-visible architectural state, however, and so it appears to be a NOP. [Internally the CPU uses the "TMP" register as a temporary storage location during execution of the XCHG operation, and so the NOP will clobber whatever value was previously held there.] One can observe two of the internal registers ("TMP" and "IND") using an invalid JMP FAR m32 opcode. Normally this is encoded as opcode FF/5 with a mod-rm byte that specifies a memory location (mod=00, mod=01, or mod=10) from which to fetch a doubleword CS:IP pointer. Specifying a mod-rm byte with mod=11 (register) - which is an undefined encoding - skips the "load doubleword from memory" microcode subroutine and causes the CPU to jump directly to the location IND:TMP instead, allowing one to observe the values held in these internal registers. At some point I'll get around to writing this up in more detail, as I don't think anyone else has ever described the behaviour of this particular invalid 8086 opcode.
- userbinator 6y agoAt some point I'll get around to writing this up in more detail, as I don't think anyone else has ever described the behaviour of this particular invalid 8086 opcode. I'd love to see more about that --- there has been plenty of documentation on "first-byte" undocumented opcodes, but far less research and information on undocumented operand combinations/groups and such. In particular, the infamous FF FF (that gets disassembled by DEBUG and a few other assemblers as "??? DI" ) falls in that area, as does LEA with a register operand ("LEA AX, AX") and several others that don't immediately come to mind. If I remember correctly, on the Z80 some of the hidden architectural registers' state was also visible as undefined flags. What you've described sounds very similar to that.
- kiwidrew 6y ago> LEA with a register operand ("LEA AX, AX") Yep, reading about this (from a post that I can't find at the moment) was one of the things that inspired me to try illegal/undefined mod-rm byte encodings.
- kens 6y ago