bound instruction before returning. Nevertheless, you should not arbitrarily modify registers in an exception handling routine unless you intend to immediately abort the execution of your program.
div or idiv instructions. Note that the FPU's fdiv and fdivr instructions do not raise this exception.div or idiv instruction.
int 3 instruction. However, we will consider it an exception since programmers rarely put int 3 instructions directly into their programs. Instead, a debugger like Codeview often manages the placement and removal of int 3 instructions.int instructions that transfer control through this vector. Generally, though, it is the one-byte int 3 instruction whose opcode is 0cch; otherwise it is the two byte equivalent: 0cdh, 03h.
int 3, is technically a trap. The CPU only raises this exception when you execute an into instruction and the overflow flag is set. If the overflow flag is clear, the into instruction is effectively a nop, if the overflow flag is set, into behaves like an int 4 instruction. Programmers can insert an into instruction after an integer computation to check for an arithmetic overflow. Using into is equivalent to the following code sequence:
<< Some integer arithmetic code » jno GoodCode int 4 GoodCode:
One big advantage to the into instruction is that it does not flush the pipeline or prefetch queue if the overflow flag is not set. Therefore, using the into instruction is a good technique if you provide a single overflow handler (that is, you don't have some special code for each sequence where an overflow could occur).
The return address on the stack is the address of the next instruction after into. Generally, an overflow handler does not return to that address. Instead, it will usually abort the program or pop the return address and flags off the stack and attempt the computation in a different way.
into, the bound instruction will cause a conditional exception. If the specified register is outside the specified bounds, the bound instruction is equivalent to an int 5 instruction; if the register is within the specified bounds, the bound instruction is effectively a nop.bound pushes is the address of the bound instruction itself, not the instruction following bound. If you return from the exception without modifying the value in the register (or adjusting the bounds), you will generate an infinite loop because the code will reexecute the bound instruction and repeat this process over and over again.bound instruction is to generate a global minimum and maximum for an array of signed integers. The following code demonstrates how you can do this:
; This program demonstrates how to compute the minimum and maximum values
; for an array of signed integers using the bound instruction
.xlist
.286
include stdlib.a
includelib stdlib.lib
.list
dseg segment para public 'data'
; The following two values contain the bounds for the BOUND instruction.
LowerBound word ?
UpperBound word ?
; Save the INT 5 address here:
OldInt5 dword ?
; Here is the array we want to compute the minimum and maximum for:
Array word 1, 2, -5, 345, -26, 23, 200, 35, -100, 20, 45
word 62, -30, -1, 21, 85, 400, -265, 3, 74, 24, -2
word 1024, -7, 1000, 100, -1000, 29, 78, -87, 60
ArraySize = ($-Array)/2
dseg ends
cseg segment para public 'code'
assume cs:cseg, ds:dseg
; Our interrupt 5 ISR. It compares the value in AX with the upper and
; lower bounds and stores AX in one of them (we know AX is out of range
; by virtue of the fact that we are in this ISR).
;
; Note: in this particular case, we know that DS points at dseg, so this
; ISR will get cheap and not bother reloading it.
;
; Warning: This code does not handle the conflict between bound/int5 and
; the print screen key. Pressing prtsc while executing this code may
; produce incorrect results (see the text).
BoundISR proc near
cmp ax, LowerBound
jl NewLower
; Must be an upper bound violation.
mov UpperBound, ax
iret
NewLower: mov LowerBound, ax
iret
BoundISR endp
Main proc
mov ax, dseg
mov ds, ax
meminit
; Begin by patching in the address of our ISR into int 5's vector.
mov ax, 0
mov es, ax
mov ax, es:[5*4]
mov word ptr OldInt5, ax
mov ax, es:[5*4 + 2]
mov word ptr OldInt5+2, ax
mov word ptr es:[5*4], offset BoundISR
mov es:[5*4 + 2], cs
; Okay, process the array elements. Begin by initializing the upper
; and lower bounds values with the first element of the array.
mov ax, Array
mov LowerBound, ax
mov UpperBound, ax
; Now process each element of the array:
mov bx, 2 ;Start with second element.
mov cx, ArraySize
GetMinMax: mov ax, Array[bx]
bound ax, LowerBound
add bx, 2 ;Move on to next element.
loop GetMinMax ;Repeat for each element.
printf
byte "The minimum value is %d\n"
byte "The maximum value is %d\n",0
dword LowerBound, UpperBound
; Okay, restore the interrupt vector:
mov ax, 0
mov es, ax
mov ax, word ptr OldInt5
mov es:[5*4], ax
mov ax, word ptr OldInt5+2
mov es:[5*4+2], ax
Quit: ExitPgm ;DOS macro to quit program.
Main endp
cseg ends
sseg segment para stack 'stack'
stk db 1024 dup ("stack ")
sseg ends
zzzzzzseg segment para public 'zzzzzz'
LastBytes db 16 dup (?)
zzzzzzseg
ends
end Main
If the array is large and the values appearing in the array are relatively random, this code demonstrates a fast way to determine the minimum and maximum values in the array. The alternative, comparing each element against the upper and lower bounds and storing the value if outside the range, is generally a slower approach. True, if the bound instruction causes a trap, this is much slower than the compare and store method. However, it a large array with random values, the bounds violation will rarely occur. Most of the time the bound instruction will execute in 7-13 clock cycles and it will not flush the pipeline or the prefetch queue[5].
Warning: IBM, in their infinite wisdom, decided to use int 5 as the print screen operation. The default int 5 handler will dump the current contents of the screen to the printer. This has two implications for those who would like to use the bound instruction in their programs. First, if you do not install your own int 5 handler and you execute a bound instruction that generates a bound exception, you will cause the machine to print the contents of the screen. Second, if you press the PrtSc key with your int 5 handler installed, BIOS will invoke your handler. The former case is a programming error, but this latter case means you have to make your bounds exception handler a little smarter. It should look at the byte pointed at by the return address. If this is an int 5 instruction opcode (0cdh), then you need to call the original int 5 handler, or simply return from interrupt (do you want them pressing the PrtSc key at that point?). If it is not an int 5 opcode, then this exception was probably raised by the bound instruction. Note that when executing a bound instruction the return address may not be pointing directly at a bound opcode (0c2h). It may be pointing at a prefix byte to the bound instruction (e.g., segment, addressing mode, or size override). Therefore, it is best to check for the int 5 opcode.
bswap, cmpxchg, etc.).