Undocumented instructions and undocumented features of Intel and IIT processors: AAD: OPCODE: d5,0a OPCODE VARIANT This instruction regularly performs the following action: - unpacked BCD in AX example (AX = 0104h) - AL = AH * 10d + AL (AL = 0eh ) - AH = 00 (AH = 00h ) The normal opcode decodes as follows: d5,0a The instruction itself is an instruction plus operand. By replacing the second byte with any number in the range 00 - ff we can build our own instruction AAD for various number systems in those ranges. For example by coding d5,10 we achieve an instruction that performs: AL = AH * 16d + AL. Note: the variant is not supported on all 80x86-compatible CPUs, notably the NEC V-series, because some hard-code the divisor at 0Ah AAM: OPCODE: d4,0a OPCODE VARIANT This instruction regularly performs the following action: - binary number in AL - AH = AL / 10d - AL = AL MOD 10d Thus creating an unpacked BCD in AX. The normal opcode decodes as follows: d4,0a The instruction itself is an instruction plus operand. By replacing the second byte with any number in the range 00 - ff we can build our own instruction AAM for various number systems in that range. For example by coding d4,07 we achieve an instruction that performs: AH = AL / 07d, AL = AL MOD 07d The AAD and AAM opcode variants have been found in Future Domain SCSI controller ROMS. LOADALL: OPCODE: 0f,05 (i80286) & 0f,07 (i80386 & i80486) UNDOCUMENTED Load _ALL_ processor registers. Does exactly as the name suggests, separate versions for i80286 and i80386 exist. The i80286 LOADALL instruction reads a block of 102 bytes into the chip, starting at address 000800 hex. The i80286 LOADALL takes 195 clocks to execute. The sequence is as follows (Hex address, Bytes, Register): 0800: 6 N/A 0806: 2 MSW (Machine Status Word) 0808: 14 N/A 0816: 2 TR (Task Register) 0818: 2 FLAGS (Flags) 081a: 2 IP (Instruction Pointer) 081c: 2 LDT (Local Descriptor Table) 081e: 2 DS (Data Segment) 0820: 2 SS (Stack Segment) 0822: 2 CS (Code Segment) 0824: 2 ES (Extra Segment) 0826: 2 DI (Destination Index) 0828: 2 SI (Source Index) 082a: 2 BP (Base Pointer) 082c: 2 SP (Stack Pointer) 082e: 2 BX (BX register) 0830: 2 DX (DX register) 0832: 2 CX (CX register) 0834: 2 AX (AX register) 0836: 6 ES cache (ES descriptor _cache_) 083c: 6 CS cache (CS descriptor _cache_) 0842: 6 SS cache (SS descriptor _cache_) 0848: 6 DS cache (DS descriptor _cache_) 084e: 6 GDTR (Global Descriptor Table) 0854: 6 LDT cache (Local Descriptor_cache_) 085a: 6 IDTR (Interrupt Descriptor table) 0860: 6 TSS cache (Task State Segment _cache_) Descriptor cache entries are internal copies of the original registers (the LDT cache is normally a copy of the last regularly _loaded_ LDT). Note that after executing LOADALL, the chip will use the _cache_ registers without re-checking the caches against the regular registers. That means that cache and register do not have to be the same. Caches are updated when the original register is loaded again. Both will then contain the same value. Descriptor caches layout: 3 bytes 24 bit physical address of segment 1 byte access rights byte, mapped as access right byte in a regular descriptor. The present bit now represents a valid bit. If this bit is cleared (zero) the segment is invalid and accessing it will trigger exception 0dh. The DPL (Descriptor Privilege Level) fields of the CS and SS descriptor caches determine the CPL (Current Privilege Level). 2 bytes 16 bit segment limit. This layout is the same for the GDTR and IDTR registers, except that the access rights byte must be zero. i80386 LOADALL: The i80386 variant loads 204 (dec) bytes from the address at ES:EDI and resumes execution in the specified state. No timing information available. relative offset: Bytes: Registers: 0000: 4 CR0 0004: 4 EFLAGS 0008: 4 EIP 000c: 4 EDI 0010: 4 ESI 0014: 4 EBP 0018: 4 ESP 001c: 4 EBX 0020: 4 EDX 0024: 4 ECX 0028: 4 EAX 002c: 4 DR6 0030: 4 DR7 0034: 4 TR 0038: 4 LDT 003c: 4 GS (zero extended) 0040: 4 FS (zero extended) 0044: 4 DS (zero extended) 0048: 4 SS (zero extended) 004c: 4 CS (zero extended) 0050: 4 ES (zero extended) 0054: 12 TSS descriptor cache 0060: 12 IDT descriptor cache 006c: 12 GDT descriptor cache 0078: 12 LDT descriptor cache 0084: 12 GS descriptor cache 0090: 12 FS descriptor cache 009c: 12 DS descriptor cache 00a8: 12 SS descriptor cache 00b4: 12 CS descriptor cache 00c0: 12 ES descriptor cache Descriptor caches layout: 1 byte zero 1 byte access rights byte, same as i80286 2 bytes zero 4 bytes 32 bit physical base address of segment 4 bytes 32 bit segment limit UNKNOWN: OPCODE: 0f,04 UNDOCUMENTED This instruction is likely to be an alias for the LOADALL on the i80286. It is not documented and is even marked as unused in the 'Programmer's technical reference'. Still it executes on the i80286. >> info wanted << SETALC: OPCODE: d6 UNDOCUMENTED This instruction copies the Carry Flag to the AL register. In case of a CY, AL becomes ffh. When the Carry Flag is cleared, AL becomes 00. .