title hel386.asm
;************************************************************************/
;*	Copyright (C) 1986-1988 Phar Lap Software, Inc.			*/
;*	Unpublished - rights reserved under the Copyright Laws of the	*/
;*	United States.  Use, duplication, or disclosure by the 		*/
;*	Government is subject to restrictions as set forth in 		*/
;*	subparagraph (c)(1)(ii) of the Rights in Technical Data and 	*/
;*	Computer Software clause at 252.227-7013.			*/
;*	Phar Lap Software, Inc., 60 Aberdeen Ave., Cambridge, MA 02138	*/
;************************************************************************/

comment #*****************************
This program demonstrates how to write
a program that uses 32-bit registers 
and addressing modes, and 80386 
instructions, but that will execute 
in Real Mode on the 80386. The program
writes a "hello world" message to
the screen.

This program must be assembled for the
80386, but linked for the 8086.
#*************************************

	assume	cs:cseg,ds:dseg

cseg segment para public use16 'CODE'
;
; The USE16 use attribute causes 
; override bytes to get generated for 
; 32-bit registers and addressing 
; modes
;
	public	main
main	proc	near

	mov	ax,dseg	; Init DS
	mov	ds,ax

;
; Load the offset of the hello 
; message into EDX, and check to 
; make sure the 16 MSBs are zero.
; An override byte is generated on
; the MOV instr to allow us to
; reference EDX, and to get a
; 32-bit offset to the string.
;
	mov	edx,offset hellomsg
	call	chk_edx
	cmp	eax,0	; jump if
	jne	#finish	; error

;
; Output the "hello world" message
; Use the 80386 SHLD instruction to
; get the DOS function code into AH
;
	mov	al,09h	; load DOS
	xor	bx,bx	; func code
	shld	ax,bx,8	; into AH
	int	21h	; call DOS

#finish:
	mov	ax,4c00h ; Call DOS
	int	21h	; to terminate

main	endp

chk_edx	proc	near
;
; This procedure checks the EDX reg
; to see if any of the 16 MSBs are set
; If so, it outputs an error message.
; Return status in EAX:
;	0	16 MSBs of EDX all 0
;	1	At least one bit set
;
	mov	eax,edx	; Check 16 
	xor	ebx,ebx	; MSBs of
	shrd	eax,ebx,16 ; EDX
	je	all_zero ; jump if 0

	call	far ptr emsg ; output
	mov	eax,1	; error msg
	ret

all_zero:
	mov	eax,0	; no error
	ret

chk_edx	endp

cseg	ends

cseg2 segment para public use16 'CODE'

emsg proc	far
;
; Example of calling a far proc.
; This procedure just outputs an
; error message
;
	mov	dx,offset errmsg
	mov	ah,09h
	int	21h
	ret

emsg endp

cseg2	ends

dseg	segment	para public 'DATA'

errmsg	db "16 MSBs of EDX were not zero"
	db	0dh,0ah,'$'

hellomsg db 'Hello world.....'
	db	0dh,0ah,'$'

dseg	ends

stack segment para stack 'STACK'
	
	db	1000 dup (?)

stack	ends

	end main
