Detabification

This commit is contained in:
Jeff Parsons 2016-02-16 12:44:38 -08:00
commit dc6c71f1fa
6 changed files with 134 additions and 83 deletions

View file

@ -21,19 +21,26 @@ From [http://www.rcollins.org/secrets/opcodes/AAD.html](http://www.rcollins.org/
|+| | | |+|+|+|+|+| | D5 | IMM8 |
+-+-+-+-+-+-+-+-+-+ +----------+----------+
This instruction is the multiplication counterpart to AAM. As is the case with AAM, AAD uses the second byte
as an operand. This operand is the multiplicand for AAD. Like AAM, AAD provides a way to execute a MUL IMM8 that
is unavailable through any other means in the CPU. Unlike MUL, or IMUL, AAD sets all of the CPU status flags
according to the result. Intel states that the Overflow Flag (OF), Auxiliary carry Flag (AF), and Carry Flag (CF)
are undefined. This assertion is incorrect. These flags are fully defined, and are set consistently with respect
to any other integer operations. And again, like AMM, beginning with the Pentium, Intel has finally acknowledged
the existence of the second byte of this instruction as its operand. Intel says:
This instruction is the multiplication counterpart to AAM. As is the
case with AAM, AAD uses the second byte as an operand. This operand is
the multiplicand for AAD. Like AAM, AAD provides a way to execute a
MUL IMM8 that is unavailable through any other means in the CPU.
Note: imm8 has the value of the instruction's second byte. The second byte under normally assembly [sic] of
this instruction will be 0A, however, explicit modification of this byte will result in the operation described
above and may alter results.
Unlike MUL, or IMUL, AAD sets all of the CPU status flags according
to the result. Intel states that the Overflow Flag (OF), Auxiliary carry
Flag (AF), and Carry Flag (CF) are undefined. This assertion is incorrect.
These flags are fully defined, and are set consistently with respect to
any other integer operations.
This instruction exists in this form on all Intel x86 processors. See the file AAD.ASM for diagnostics source code
for this instruction.
And again, like AMM, beginning with the Pentium, Intel has finally
acknowledged the existence of the second byte of this instruction as its
operand. Intel says:
Note: imm8 has the value of the instruction's second byte. The
second byte under normally assembly [sic] of this instruction will
be 0A, however, explicit modification of this byte will result in
the operation described above and may alter results.
This instruction exists in this form on all Intel x86 processors.
See [AAD.ASM](AAD.ASM) for the source code mentioned above.
See the file [AAD.ASM](AAD.ASM) for diagnostic source code for this instruction.

View file

@ -21,31 +21,42 @@ From [http://www.rcollins.org/secrets/opcodes/AAM.html](http://www.rcollins.org/
|0| | | |+|+|0|+|0| | D4 | IMM8 |
+-+-+-+-+-+-+-+-+-+ +----------+----------+
AAM is shown as a two byte encoding used to divide AL by 10, putting the quotient in AH, and the remainder in AL.
However, AAM is listed in the op code map as a single byte instruction. This leads one to wonder why a two-byte
opcode is listed in the single-byte opcode map. In reality, the second byte is an undocumented operand to AAM.
The operand is the divisor. In its documented incarnation, AAM is encoded as D4 0A. The operand 0A is the divisor.
This divisor can be changed to any value between 0 and FF. Using AAM in this manner is useful -- as it extends the
CPU instruction set to include a DIV IMM8 instruction that is not available from any other form of the DIV
instruction.
AAM is shown as a two byte encoding used to divide AL by 10, putting
the quotient in AH, and the remainder in AL. However, AAM is listed in
the op code map as a single byte instruction. This leads one to wonder
why a two-byte opcode is listed in the single-byte opcode map.
The extended form of the AAM instruction is also useful because it sets the flags register according to the results,
unlike the DIV or IDIV instruction. According to Intel documentation, SF, ZF, and PF flags are set according to the
result, while OF, AF, and CF are undefined. However, if AAM were used strictly as documented, then the Sign Flag (SF)
could not be set under any circumstances, since anything divided by 10 will leave a remainder between 0 and 9.
Obviously the remainder could never be between 128 and 255 (or -1 and -128 if you prefer) if used only as documented.
Since AAM divides an 8 bit number by another 8-bit number, a carry or overflow could never occur. Therefore CF and
OF always=0. Intel claims they are undefined, but my observations are consistent with my theory.
In reality, the second byte is an undocumented operand to AAM. The operand
is the divisor. In its documented incarnation, AAM is encoded as D4 0A.
The operand 0A is the divisor. This divisor can be changed to any value
between 0 and FF. Using AAM in this manner is useful -- as it extends the
CPU instruction set to include a DIV IMM8 instruction that is not available
from any other form of the DIV instruction.
Contrary to documentation, AAM will generate exceptions in real mode, protected mode, and V86 mode. AAM can only
generate Exception 0 -- divide by 0. Finally, in the Pentium User's Manual, this heretofore undocumented form of
The extended form of the AAM instruction is also useful because it sets the
flags register according to the results, unlike the DIV or IDIV instruction.
According to Intel documentation, SF, ZF, and PF flags are set according
to the result, while OF, AF, and CF are undefined. However, if AAM were used
strictly as documented, then the Sign Flag (SF) could not be set under any
circumstances, since anything divided by 10 will leave a remainder between
0 and 9. Obviously the remainder could never be between 128 and 255 (or -1
and -128 if you prefer) if used only as documented. Since AAM divides an
8-bit number by another 8-bit number, a carry or overflow could never occur.
Therefore CF and OF always=0. Intel claims they are undefined, but my
observations are consistent with my theory.
Contrary to documentation, AAM will generate exceptions in real mode,
protected mode, and V86 mode. AAM can only generate Exception 0 -- divide
by 0.
Finally, in the Pentium User's Manual, this heretofore undocumented form of
AMM is described. Intel says:
Note: imm8 has the value of the instruction's second byte. The second byte under normally assembly [sic] of
this instruction will be 0A, however, explicit modification of this byte will result in the operation described
above and may alter results.
Note: imm8 has the value of the instruction's second byte. The
second byte under normally assembly [sic] of this instruction will
be 0A, however, explicit modification of this byte will result in
the operation described above and may alter results.
This instruction exists in this form on all Intel x86 processors. See the file AAM.ASM for diagnostics source code
for this instruction.
This instruction exists in this form on all Intel x86 processors.
See [AAM.ASM](AAM.ASM) for the source code mentioned above.
See the file [AAM.ASM](AAM.ASM) for diagnostic source code for this instruction.

View file

@ -11,15 +11,23 @@ ICEBP (0xF1)
From [http://www.rcollins.org/secrets/opcodes/UMOV.html](http://www.rcollins.org/secrets/opcodes/UMOV.html):
An undocumented op code that will make debugging run-time code on an ICE easier. Normally, to set an arbitrary
breakpoint in a program which was loaded by an operating system, you must perform a laborious task of figuring out
where your program was loaded in memory. Follow that process with an equally laborious task of calculating the
offset in memory which corresponds to the desired breakpoint. This process is exacerbated by programs which use
many segments, especially many code segments. Now for one final complication, consider that your program switches
from real mode, to protected mode, with paging enabled, and you are not using a 1-to-1 mapping of physical to
virtual memory. You want to talk about a nightmare just to figure out where to set a breakpoint?
An undocumented op code that will make debugging run-time code
on an ICE easier. Normally, to set an arbitrary breakpoint in a
program which was loaded by an operating system, you must perform
a laborious task of figuring out where your program was loaded
in memory. Follow that process with an equally laborious task of
calculating the offset in memory which corresponds to the desired
breakpoint.
All of these problems are eliminated, simply by using this instruction -- provided you know its caveats.
This process is exacerbated by programs which use many segments,
especially many code segments. Now for one final complication,
consider that your program switches from real mode, to protected mode,
with paging enabled, and you are not using a 1-to-1 mapping of physical
to virtual memory. You want to talk about a nightmare just to figure
out where to set a breakpoint?
All of these problems are eliminated, simply by using this instruction
-- provided you know its caveats.
Undocumented: Available to all 80386-class (and above)
processors as described herein.
@ -36,30 +44,41 @@ From [http://www.rcollins.org/secrets/opcodes/UMOV.html](http://www.rcollins.org
| | | | | | | | | | | F1 |
+-+-+-+-+-+-+-+-+-+ +----------+
The name ICEBP was given by a pre-production Intel ICE that had the ability to disassemble undocumented op codes.
The name ICEBP is a misnomer because the instruction is actually a single byte single-step exception (INT-01).
The name ICEBP was given by a pre-production Intel ICE that had the
ability to disassemble undocumented op codes. The name ICEBP is a
misnomer because the instruction is actually a single byte single-step
exception (INT-01).
How you use ICEBP depends upon whether or not you are using an 80386 ICE, Intel486 ICE, or Pentium ICE. For the
purposes of this article, usage of ICEBP on 80386 and Intel486 are identical. Pentium enables ICEBP a little
differently than its predecessors.
How you use ICEBP depends upon whether or not you are using an 80386
ICE, Intel486 ICE, or Pentium ICE. For the purposes of this article,
usage of ICEBP on 80386 and Intel486 are identical. Pentium enables
ICEBP a little differently than its predecessors.
Two effects of ICEBP -- 80386 and Intel486
ICEBP has two operational effects: When Interrupt Redirection (IR) is disabled, ICEBP acts as a single byte INT 01.
When this instruction occurs, it invokes the standard INT 01 handler. Unlike the single step exception (Trap Flag=1),
this instruction does not set the trap flag on the stack image, nor modifies the trap flag on the stack image.
Therefore, upon termination of the INT 01 handler, execution continues without further occurrences of the single
step breakpoints.
ICEBP has two operational effects: When Interrupt Redirection (IR) is
disabled, ICEBP acts as a single byte INT 01. When this instruction occurs,
it invokes the standard INT 01 handler. Unlike the single step exception
(Trap Flag=1), this instruction does not set the trap flag on the stack
image, nor modifies the trap flag on the stack image. Therefore, upon
termination of the INT 01 handler, execution continues without further
occurrences of the single step breakpoints.
When Interrupt Redirection is enabled, ICEBP will attempt to invoke the hardware breakpoint handler associated with
an In Circuit Emulator (ICE). If the processor is a production CPU, the processor will hang. If the processor is a
BONDOUT CPU attached to an ICE, ICEBP will cause the ICE to break from emulation. On an Intel ICE, the message
"Unknown Breakpoint at address xxxx:xxxx:xxxxxxxx" appears on the screen.
When Interrupt Redirection is enabled, ICEBP will attempt to invoke the
hardware breakpoint handler associated with an In Circuit Emulator (ICE).
If the processor is a production CPU, the processor will hang. If the
processor is a BONDOUT CPU attached to an ICE, ICEBP will cause the ICE
to break from emulation. On an Intel ICE, the message "Unknown Breakpoint
at address xxxx:xxxx:xxxxxxxx" appears on the screen.
There are two ways to enable Interrupt Redirection. It can be done by directly programming DR7 (see "Undocumented
Bits in DR7"), or this bit can be set (indirectly) using an ICE. To set this bit using an ICE, you must first be in
HALT mode. Any "go til" command that uses the debug registers will enable Interrupt Redirection. For example,
"go til 1234:5678 execute," "go til 1025:3245 write," or simply "go til 0 p" will enable Interrupt Redirection.
This work because the ICE actually uses the debug registers to trap debug exceptions. Of course, this directly
implies that any time the ICE uses the debug registers to signify break points, and emulation halts, it does so
following an INT 01 to the ICE break point handler (since interrupt redirection is enabled).
There are two ways to enable Interrupt Redirection. It can be done by
directly programming DR7 (see "Undocumented Bits in DR7"), or this bit
can be set (indirectly) using an ICE. To set this bit using an ICE, you
must first be in HALT mode. Any "go til" command that uses the debug
registers will enable Interrupt Redirection. For example, "go til 1234:5678
execute," "go til 1025:3245 write," or simply "go til 0 p" will enable
Interrupt Redirection. This work because the ICE actually uses the debug
registers to trap debug exceptions. Of course, this directly implies that
any time the ICE uses the debug registers to signify break points, and
emulation halts, it does so following an INT 01 to the ICE break point
handler (since interrupt redirection is enabled).

View file

@ -11,9 +11,11 @@ LOADALL386 (0x070F)
From [http://www.rcollins.org/secrets/opcodes/LOADALL.html](http://www.rcollins.org/secrets/opcodes/LOADALL.html):
(LOADALL) An undocumented op code used by ICE host software and diagnostics software to test CPU functionality.
This instruction has the ability to bypass the entire protection checking mechanism in the CPU, and therefore can
be used to test many aspects of CPU behavior that can't be duplicated by any other software means.
(LOADALL) An undocumented op code used by ICE host software and
diagnostics software to test CPU functionality. This instruction
has the ability to bypass the entire protection checking mechanism
in the CPU, and therefore can be used to test many aspects of CPU
behavior that can't be duplicated by any other software means.
Read LOADALL magazine article and download LOADALL demo source code.

View file

@ -11,9 +11,10 @@ SALC (0xD6)
From [http://www.rcollins.org/secrets/opcodes/SALC.html](http://www.rcollins.org/secrets/opcodes/SALC.html):
An undocumented op code that performs an operation common to every Assembly language subroutine to C and many
other higher level languages. This instruction is a C programmers 'dream' instruction for interfacing to assembly
language.
An undocumented op code that performs an operation common to
every Assembly language subroutine to C and many other higher
level languages. This instruction is a C programmers 'dream'
instruction for interfacing to assembly language.
Undocumented: Available to all Intel x86 processors
Useful in production source code.
@ -25,16 +26,26 @@ From [http://www.rcollins.org/secrets/opcodes/SALC.html](http://www.rcollins.org
| | | | | | | | | | | D6 |
+-+-+-+-+-+-+-+-+-+ +----------+
The name SALC simply stands for SET the Carry flag in AL. This instruction is categorized as an undocumented
single-byte proprietary instruction. Intel claims it can be emulated as a NOP. Hardly a NOP, this instruction
sets AL=FF if the Carry Flag is set (CF=1), or resets AL=00 if the Carry Flag is clear (CF=0). It can best be
emulated as SBB AL,AL. SALC doesn't change any flags, where SBB AL,AL does. This instruction is most useful to
high-level language programmers whose programs call assembly language, and expect AL to indicate success or failure.
Since it is convenient for assembly language programs to return status in the CF, this instruction will convert
that status to a form compatible with high level languages.
The name SALC simply stands for SET the Carry flag in AL. This
instruction is categorized as an undocumented single-byte proprietary
instruction. Intel claims it can be emulated as a NOP. Hardly a NOP,
this instruction sets AL=FF if the Carry Flag is set (CF=1), or resets
AL=00 if the Carry Flag is clear (CF=0). It can best be emulated as
SBB AL,AL. SALC doesn't change any flags, where SBB AL,AL does.
Over the years, this instruction has been given many names by various discoverers. I originally gave it the name
SETCAL, but the most common name I've seen in print is SETALC. The name given above, SALC is an official Intel name.
While perusing the P6 opcode map, I always check for known, undocumented opcodes. After weeding through the map
for many minutes, my patience and perseverance paid off. I found the opcode, and its name. Intel's name for this
opcode is SALC. This would indicate that Intel plans to officially document this instruction, beginning with the P6.
This instruction is most useful to high-level language programmers
whose programs call assembly language, and expect AL to indicate success
or failure. Since it is convenient for assembly language programs to
return status in the CF, this instruction will convert that status to a
form compatible with high level languages.
Over the years, this instruction has been given many names by various
discoverers. I originally gave it the name SETCAL, but the most common
name I've seen in print is SETALC. The name given above, SALC is an
official Intel name.
While perusing the P6 opcode map, I always check for known, undocumented
opcodes. After weeding through the map for many minutes, my patience and
perseverance paid off. I found the opcode, and its name. Intel's name for
this opcode is SALC. This would indicate that Intel plans to officially
document this instruction, beginning with the P6.

View file

@ -11,7 +11,8 @@ UMOV (0x100F,0x110F,0x120F,0x130F)
From [http://www.rcollins.org/secrets/opcodes/UMOV.html](http://www.rcollins.org/secrets/opcodes/UMOV.html):
An undocumented op code used by ICE host software to perform memory cycles to the target system during HALT mode.
An undocumented op code used by ICE host software to perform
memory cycles to the target system during HALT mode.
Undocumented: Available on all 80386/80486 processors.
Useful only to BONDOUT (ICE) processors.