;SEARCH_HALF--G5_20
;Search an ordered list in the extra segment for the word
;  value contained in AX
;Inputs: ES:DI=starting address of the list
;	 First location=Length of list(words)
;Results:If the value is in the list,
;    	    CF=0
;	    SI=Offset of matching element.
;	 If thr value is not in the list,
;	    CF=1
;	    SI=Offset of last element compared.
;**********************************************************
dseg    segment		;define data segment
  start_addr	dw	?
dseg    ends
;**********************************************************
eseg	segment
  list	dw	12,11,22,33,44,55,66,77,88,99,111,222,333
eseg	ends
;**********************************************************
cseg    segment			;defint code segment
;----------------------------------------------------------
main	proc	far
	assume	cs:cseg,ds:dseg,es:eseg
start:
	push	ds
	sub	ax,ax
	push	ax
;
	mov	ax,dseg
	mov	ds,ax
	mov	ax,eseg
	mov	es,ax
;
	lea	di,list
	mov	ax,55
	call	b_search
	ret
main	endp
;------------------------------------------------------
b_search	proc	near	
	push	ds		;save caller's DS

;Find out if AX lies beyond the boundaries of the list.
	cmp	ax,es:[di+2]	;search value<or=first el.?
	ja	chk_last	;no,go check last el.
	lea	si,es:[di+2]	;yes,fetch addr of first el.
	je	exit		;if value =1st el.,exit
	stc			;if value < 1st el.,set CF
	jmp	exit		;  and then exit
chk_last:
	mov	si,es:[di]	;point to last el.
	shl	si,1
	add	si,di
	cmp	ax,es:[si]	;search value>or=last el.?
	jb	search		;no, go search list
	je	exit		;yes, exit if value =last el.
	stc			;if value >last el.,set CF
	jmp	exit		;  and then exit
; Search for value within the list.
search:	mov	start_addr,di	;save starting addr in memory
	mov	si,es:[di]	;fetch index
even_idx:
	test	si,1		;force index to an even value
	jz	add_idx
	inc	si
add_idx:add	di,si		;calculate next search addr 
compare:cmp	ax,es:[di]	;search value found?
	je	all_done	;if so,exit
	ja	higher		;otherwise, find correct half
; These instructions are executed if the search value is
;   lower in the list.
	cmp	si,2		;index = 2?	
	jne	idx_ok	
no_match:
	stc			;if so, set CF
	je	all_done	;  and exit
idx_ok:	shr	si,1		;if not, divide index by 2
	test	si,1		;force index to
				;  an even value
	jz	sub_idx	
	inc	si
sub_idx:sub	di,si		;calaulate next addr
	jmp	short compare	;go check this el.
; These instructions are executed if the search value is
;   higher in the list.
higher:	cmp	si,2		;index = 2 ?	
	je	no_match	;if so, go set CF and exit
	shr	si,1		;if not, divide index by 2
	jmp	short even_idx	;go check next el.
; Following are exit instructions.
all_done:
	mov	si,di		; move compare addr into SI
	mov	di,start_addr	;restore starting addr
exit:	pop	ds	
	ret			;  and exit 

b_search	endp		
;----------------------------------------------------------
cseg    ends			;end of code segment
;**********************************************************
	end			;end assembly
