ID Number: Q80379
2.x 3.00 3.10 3.11 3.14
MS-DOS
Summary:
Code that is written to modify it's own contents may run differently
when run one line at a time in the Microsoft CodeView Debugger (CV).
This occurs because of the the way the 80x86 processors fetch
instructions. Because this is a limitation of how CodeView works, care
should be used when debugging self-modifying code.
The code may run one way outside of CodeView, and another way from
within CodeView. Also, running the program by using the go (F5)
command instead of the step (F10) or trace (F8) command may affect the
program's execution. Different processors can also affect this
behavior.
More Information:
The 80x86 processor will try to pre-fetch the next instruction from
memory while processing the current instruction. If the code being
modified is already waiting in the instruction queue, then the
processor will run the unmodified code. However, a jump instruction
will invalidate the queue, causing the next instruction to be fetched
before execution. In self-modifying code, this will cause the modified
instruction to be run. When stepping through a program in CodeView,
the instruction queue is always marked invalid, so all modified
instructions are run. The code below demonstrates this behavior.
If you step through the sample code in CodeView it will output "Num =
1". If you run straight though the code, allowing the processor to
pre-fetch instructions, it will output "Num = 0".
Sample Code
-----------
/* Compile options needed: /Zi
*/
#include<stdio.h>
void main(void)
{
unsigned int Num;
_asm {
mov ax, cs
push ds
mov ds, ax
inc byte ptr [cnt + 1] /* Adding a "jmp cnt" between the */
cnt: mov ax, 0 /* INC and the MOV will cause the */
mov Num, ax /* modified code to be run */
pop ds
}
printf("Num = %d",Num);
}
Additional reference words: 3.00 3.10 2.20