Code:
#COMPILE EXE
#DIM ALL
#OPTIMIZE SPEED

FUNCTION asmBinarySearch (BYVAL plArray AS LONG PTR, BYVAL lUBound AS LONG, BYVAL lValue AS LONG) AS LONG

	'Returns subscript from array( 1 TO lUBound) matching lValue if found, else returns 0
	'Assumes array is base 0
	'Max value in array must be <= 1,073,741,823

	!mov esi, 1
	!mov edi, lUBound

	!mov edx, lValue
	!mov eax, plArray
DoStart:
	!mov ecx, esi
	!add ecx, edi
	!shr ecx, 1                  ;ecx = (I + J) \ 2
	!cmp [eax]+[ecx * 4], edx
	!jg  short AdjustJ           ;IF @plArray[ ecx] > lValue THEN GOTO AdjustJ
	!jl  short AdjustI           ;IF @plArray[ ecx] < lValue THEN GOTO AdjustJ
	!mov FUNCTION, ecx           ;@plArray[ ecx] = lValue, return ecx
	EXIT FUNCTION

AdjustJ:
	!mov edi, ecx                ;J = ecx - 1
	!dec edi
	!cmp edi, esi
	!jge short DoStart           ;IF J >= I THEN GOTO DoStart
	EXIT FUNCTION

AdjustI:
	!mov esi, ecx                ;I = ecx + 1
	!inc esi
	!cmp edi, esi
	!jge short DoStart           ;IF J >= I THEN GOTO DoStart

END FUNCTION

FUNCTION pbBinarySearch (BYVAL plArray AS LONG PTR, BYVAL lUBound AS LONG, BYVAL lValue AS LONG) AS LONG

	'Returns subscript from array( 1 TO lUBound) matching lValue if found, else returns 0
	'Assumes array is base 0
	'Max value in array can be up to limit of LONG values

	REGISTER I AS LONG, J AS LONG

	LOCAL lIndex AS LONG

	'Find key
	I = 1
	J = lUBound

	DO
	  lIndex = (I + J) \ 2
	  SELECT CASE AS LONG @plArray[ lIndex]
		  CASE > lValue
			  J = lIndex - 1
		  CASE < lValue
			  I = lIndex + 1
		  CASE ELSE  ' = lValue
			  FUNCTION = lIndex
			  EXIT FUNCTION
	  END SELECT
	LOOP UNTIL J < I

END FUNCTION

FUNCTION BinSrch(BYVAL ArrayAddr AS LONG, BYVAL dItem AS DWORD, BYVAL NumItens AS DWORD) AS DWORD

	'http://www.powerbasic.com/support/pbforums/showthread.php?t=4296 (vBulletin)
	'http://www.powerbasic.com/support/forums/Forum4/HTML/004379.html (POFFs)
	'Roberto Valois
	'Assumes array is base 1
	'Max value in array must be <= 1,073,741,823

	!mov esi,ArrayAddr    ' ESI = Array base addr
	!mov edx,dItem         ' EDX = Item to be found
	!xor ebx,ebx          ' EBX = Low - First item
	!mov ecx,NumItens     ' ECX = High - Last Item
	!dec ecx              ' Adjust High - We are now zero based, Low = 0 and High = NumItens - 1
	AGAIN:
	!cmp ecx,ebx          ' High have to be >= Low
	!jl short NOTFOUND    ' If not get out
	!mov eax,ebx          ' Mid = Low
	!add eax,ecx          ' Mid = Low + High
	!shr eax,1            ' Mid = (Low + High) \ 2
	!cmp edx,[esi+eax*4]  ' Compare Item with (Mid)
	!jg short GT          ' Item > (Mid) ?
	!jl short LT          ' Item < (Mid) ?
	!inc eax              ' Found ! Item = (Mid). Adjust Mid to 1 based
	!jmp short FOUND      ' Happy get out
	LT:
	!mov ecx,eax          ' High = Mid
	!dec ecx              ' High = Mid - 1
	!jmp short AGAIN      ' Play it again Sam
	GT:
	!mov ebx,eax          ' Low = Mid
	!inc ebx              ' Low = Mid + 1
	!jmp short AGAIN      ' Play it again Sam
	NOTFOUND:
	!xor eax,eax          ' eax = %False
	FOUND:
	!mov Function,eax     ' Function = what is in eax

END FUNCTION

%NumElements = 10000
%NumTests = 1000000

FUNCTION PBMAIN () AS LONG

	LOCAL I AS LONG, J AS LONG
	LOCAL qpbBinarySearchTix AS QUAD, qasmBinarySearchTix AS QUAD, qasmBinSrchTix AS QUAD
	LOCAL lResult1 AS LONG, lResult2 AS LONG

	DIM lData( %NumElements) AS LOCAL LONG
	DIM lValues( %NumTests) AS LOCAL LONG

	RANDOMIZE TIMER

	'Seed array with data
	FOR I = 1 TO %NumElements
		lData( I) = RND( 1, %NumElements)
	NEXT

	'Sort Data
	ARRAY SORT lData( 1)

	DO
		'Make array of test values
		FOR I = 1 TO %NumTests
			lValues( I) = RND( 1, %NumElements)
		NEXT

		'Test pbBinarySearch
		TIX qpbBinarySearchTix
		FOR I = 1 TO %NumTests
			J = pbBinarySearch( VARPTR( lData( 0)), %NumElements, lValues( I))
		NEXT
		TIX END qpbBinarySearchTix

		lResult1 = J

		'Test pbBinarySearch
		TIX qasmBinSrchTix
		FOR I = 1 TO %NumTests
			J = BinSrch( VARPTR( lData( 1)), lValues( I), %NumElements)
		NEXT
		TIX END qasmBinSrchTix

		lResult2 = J

		'Test asmBinarySearch
		TIX qasmBinarySearchTix
		FOR I = 1 TO %NumTests
			J = asmBinarySearch( VARPTR( lData( 0)), %NumElements, lValues( I))
		NEXT
		TIX END qasmBinarySearchTix

	LOOP UNTIL MSGBOX( "pbBinarySearch took " + FORMAT$( qpbBinarySearchTix, "#,") + " tix.  Found " + FORMAT$( lValues( %NumTests)) + " at lData( " + FORMAT$( lResult1) + ") = " + FORMAT$( lData( lResult1)) + $CRLF + $CRLF + _
			 "BinSrch took " + FORMAT$( qasmBinSrchTix, "#,") + " tix.  Found " + FORMAT$( lValues( %NumTests)) + " at lData( " + FORMAT$( lResult2) + ") = " + FORMAT$( lData( lResult2)) + $CRLF + $CRLF + _
			 "asmBinarySearch took " + FORMAT$( qasmBinarySearchTix, "#,") + " tix.  Found " + FORMAT$( lValues( %NumTests)) + " at lData( " + FORMAT$( J) + ") = " + FORMAT$( lData( J)) + $CRLF + $CRLF + _
			 "Test again?", %MB_ICONQUESTION OR %MB_YESNO, "Binary Search") = %IDNO


END FUNCTION