Recently, when I was studying the DOS boot sectors, I discovered a rather mysterious thing. DOS recognizes whether the boot sector is bootable, by several criteria, and one of them (
odd, yes? ) - is there a jump-instruction in the first two bytes, which indicates, respectively, somewhere behind BPB. In the MSDISK.INC module from
MS-DOS 3.21 OAK, just such checks occur. The module checks whether the BPB begins with a jump, and accepts EBh (short JMP), E9h (JMP), or 69h opcodes for the correct jump-instruction. Stop. 69? This is an IMUL!
Nah, not IMUL. A comment in the code states that this is a “direct jump”:
cmp byte ptr cs: [DiskSector], 069H; Is it a direct jump?
je Check_Signature; don't need to find a nop
cmp byte ptr cs: [DiskSector], 0E9H; DOS 2.0 jump?
je Check_Signature; no need for NOP
cmp byte ptr cs: [DiskSector], 0EBH; How about a short jump.
jne baddisk
Well, that's just nothing about 69h in the 8086 documentation! Yes, in 8186 and further is the IMUL opcode, but the fact that 8086 can do IMUL is extremely unlikely. Moreover, the comment clearly indicates that this is a jump.
Maybe on the 8086 69h processors behaves like a jump? The question is good, but there is almost no information on this.
I thought that someone from an old hacker get-together for early PCs would surely find out exactly what undocumented instructions are doing, but I was mistaken - a rather deep search all over the Internet did not give any intelligible results, and even the book by Frank van Gilluwe "Undocumented PC ”, In which quite a lot was said about operational codes that are not described in the documentation, did not help much. Surely, sometime, somewhere, someone has published something ...
')
First, it would be nice to note that starting from 80186, unlike 8086/8088, an attempt to execute an incorrect (undocumented) opcode will cause a corresponding exception (now denoted as #UD). That is, now the opcode is either standard and executed, or #UD is triggered, and, accordingly, there is no point in trying to perform anything other than the instructions described in the documentation.
Well, of course there are exceptions: D6h and F1h - Intel has made it clear that standards do not care about it ... but let us return again to 8086
For 8086, it was not described how he should behave if they try to execute the wrong instruction on it. Undefined behavior means that each, even an undescribed instruction, definitely does
something , and that something can easily hang the processor. At least it is not prohibited.
There are several 8086 opcodes that are not described in the Intel documentation, but whose behavior
has long been established :
- POP CS (0Fh). Pretty easy to guess what he is doing. See: 06h (push es) - 07h (pop es), 16h (push ss) - 17h (pop ss), 1Eh (push ds) - 1Fh (pop ds), 0Eh (push cs) - and, accordingly, 0Fh ( pop cs). This instruction, although it works, is almost useless. That is why it has never been documented, and, starting from 80286, another instruction corresponds to the 0Fh opcode.
- MOV CS (8Eh). Same as with POP CS - pretty easy to guess, and again - useless.
- SETALC / SALC (D6h). Does the same as SBB AL, AL, but does not touch the flags, that is, AL will either have FFh or 0 depending on CF. This instruction is present in modern Intel CPUs, but it is still undocumented.
Three instructions are fine, but for 8086 60h - 6Fh (including our 69h), C0h - C1h, C8h - C9h, and F1h are also undefined. There are also several spaces in opcode extensions (this is when the instruction is described not only by the first byte, but also by part of the bits in the next byte), especially the GRP4 group,
here .
To clarify this matter, Raúl Gutiérrez Sanz took his Siemens 8086-2 (produced in 1990) and figured out what exactly is happening when executing opcodes that are not described in the official documentation.

This processor is manufactured under the license of Intel, and, without any suspicion, it is not functionally different from the original Intel processors.
Solution
Unfortunately, the behavior of most undocumented opcodes is quite prosaic. No magical secret instructions — these instructions are merely aliases to other documented ones. In other words, the 8086 processor, when decoding such instructions, simply ignores some bits of the word, and that's it :(
The undocumented opcodes 60h - 6Fh correspond to the same instructions as the documented 70h - 7Fh - the processor ignores the fourth bit of the opcode, that is, 60h corresponds to 70h, 61h - 71h, ..., 6Eh - 7Eh, 6Fh - 7Fh, and they do exactly same. Quite reasonable, especially - for the slow 8086 - no potentially dangerous behavior, and there is no need to write too much microcode. On the other hand, these initially undocumented opcodes can then be assigned to other instructions in new generation processors, while maintaining backward compatibility (after all, it is assumed that none of the code will describe undescribed opcodes).
Thus, in the C0h - CFh range, the CPU ignores the first bit of the word: C0h means C2h, C1h - C3h, C8h - CAh, and C9h - CBh.
The behavior of the opcode F1h currently remains a mystery. On the new processors, F1h is an undocumented ICEBP instruction, or INT1. In the documentation of Intel, it is not described, although AMD is present.
At 8088, F1h rather not even an instruction, but a prefix. We determined this by following the sequence consisting of repeated F1h opcodes and some other documented one. The microprocessor steps over the entire sequence, which actually proves that F1h is a kind of prefix.
It seems that F1h is an alias to F0h - the prefix LOCK. We somehow failed to prove or disprove this, because we need some piece of hardware capable of tracking the LOCK # signal on the bus.
Back to the boot sector. Could the boot sector start from 69h? At 8088, this would probably work. If opcode 69h is an alias to the JNS instruction, then if the sign flag is not set, then a short jump will be executed. At least on the IBM PC, the state of the flags at the beginning of the boot sector execution is predictable, so 69h could work.
But what's the point of putting 69h in the beginning of the boot sector and who would need it? Good question. At the moment I don’t know if there were any DOS boot sectors starting with opcode 69h. For what it was necessary for someone to use undocumented instructions completely incomprehensible. Maybe the incorrect implementation of the copy protection system ... but the fact is that DOS separately checks the beginning of the boot sector for the presence of the opcode 69h, and it absolutely proves that such boot sectors definitely existed. Ideas?
PS There are some more undocumented opcodes in the range of extended codes! More on this next time ...