Trap flag

From Infogalactic: the planetary knowledge core
Jump to: navigation, search

A trap flag permits operation of a processor in single-step mode. If such a flag is available, debuggers can use it to step through the execution of a computer program.

Single-step interrupt

When a system is instructed to single-step, it will execute one instruction and then stop. The contents of registers and memory locations can be examined; if they are correct, the system can be told to go on and execute the next instruction. The Intel 8086 Trap Flag and type-1 interrupt response make it quite easy to implement a single-step feature in an 8086-based system. If the Trap Flag is set, the 8086 will automatically do a type-1 interrupt after each instruction executes. When this happens, the CPU pushes the flag register on the stack then does a type-1 interrupt.

Setting

The 8086 has no instruction to directly set or clear the trap flag. Instead, the entire status register (known as the 16-bit Flags Register in Real Mode, the 32-bit EFlags Register in Protected Mode, or the 64-bit RFlags Register in Long Mode) must be addressed by pushing it on the stack, changing the Trap Flag bit as desired, and then popping the value off the stack and back into the Flag Register. The easiest way to do this is:

PUSHF                      ; Push flags on stack
MOV BP, SP                 ; Copy SP to BP for use as index
OR WORD PTR[BP+0], 0100H   ; Set bit 8, the Trap flag
POPF                       ; Copy the newly modified value back to the Flags Register

The Trap Flag is usually used in conjunction with a type-1 interrupt handler which will allow viewing of the register values and memory addresses of the program being single-stepped. That Interrupt Service Routine might look something like:

Int1ServiceRoutine:       ; Stack: Ret, Flags
  PUSHA                   ; Stack: Ret, Flags, AX, CX, DX, BX, SP, BP, SI, DI
  PUSH DS                 ; Stack: Ret, Flags, AX, CX, DX, BX, SP, BP, SI, DI, DS
  PUSH ES                 ; Stack: Ret, Flags, AX, CX, DX, BX, SP, BP, SI, DI, DS, ES


  ... the rest of the ISR code would go here, and should only use general purpose registers to avoid having to save and restore the FPU state


  MOV BP, SP               ; Stack: Ret, Flags, AX, CX, DX, BX, SP, BP, SI, DI, DS, ES
  MOV BP, [BP+10]          ; Copy the value of SP on the stack to the BP register for use as an index
  OR WORD PTR[BP+0], 0100H ; Set the Trap flag in the stored Flag register
  POP ES                   ; Stack: Ret, Flags, AX, CX, DX, BX, SP, BP, SI, DI, DS
  POP DS                   ; Stack: Ret, Flags, AX, CX, DX, BX, SP, BP, SI, DI
  POPA                     ; Stack: Ret, Flags
  IRET                     ; continue execution for ONE instruction, after which this ISR gets called again

Resetting

To set the trap flag, simply replace the OR instruction in the preceding sequence with the instruction:

AND WORD PTR[BP+0], 0FEFFH

The trap flag is automatically cleared by the 8086 when a type-1 interrupt occurs so that the interrupt handler itself will not be single-stepped. The initial value of the flags register which contains the trap flag is preserved on the stack and restored upon exiting the handler so that another type-1 interrupt will be generated upon completion of the next instruction.

Status register
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0 (bit position)
- - - - O D I T S Z - A - P - C Flags