Detabification
This commit is contained in:
parent
58a6f9ce3f
commit
dc6c71f1fa
6 changed files with 134 additions and 83 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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).
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue