





					   Operands and	Expressions



		 5.1  Introduction

		 This chapter describes	the syntax and	meaning	 of
		 operands and expressions used in assembly language
		 statements  and  directives.  Operands	  represent
		 values, registers, or memory locations	to be acted
		 on by instructions or directives.  Expressions	are
		 combinations  of operands and arithmetic, logical,
		 bitwise, and attribute	operators.   An	 expression
		 evaluates  to	a  value  or  memory location to be
		 acted on by an	instruction or directive.


		 5.2  Operands

		 An operand is	a  constant,  label,  variable,	 or
		 other	symbol	that  is  used in an instruction or
		 directive  to	represent  a  value,  register,	 or
		 memory	location to be acted on.

		 There are the following operand types:

		      Constant			     Direct Memory
		      Relocatable		   Location Counter
		      Register		  Based		    Indexed
		      Based Indexed	    Structure	     Record
		      Record Field















								5-1



















	      XENIX Macro Assembler Reference Manual



	      5.2.1  Constant Operands

	      Syntax

		   number | string | expression

	      An constant operand is a number, string  constant,
	      symbol,  or  expression  that evaluates to a fixed
	      value.  Constant operands, unlike	other  operands,
	      represent	values to be acted on rather than memory
	      addresses.

	      Examples

		   mov	   ax, 9		 mov	 al, 'c'
		   mov	   bx, 65535/3	    mov	    cx,	count



	      5.2.2  Direct Memory Operands

	      Syntax

		   segment : offset

	      A	direct memory operand is a pair	of  segment  and
	      offset  values  that represent the absolute memory
	      address of  one  or  more	 bytes	of  memory.  The
	      segment  can  be	a segment register name	(CS, DS,
	      SS, or ES), a segment name, or a group name.   The
	      offset  must  be	an  integer, absolute symbol, or
	      expression that evaluates	to a  value  within  the
	      range 0 to 65,535.

	      Examples

		   mov	   dx, ss:0031H	      mov     bx, DATA:0
		   mov	   cx, DGROUP:block




	      5-2



















					   Operands and	Expressions



		 5.2.3	Relocatable Operands

		 Syntax

		      symbol

		 A  relocatable	 operand   is	any   symbol   that
		 represents the	memory address (segment	and offset)
		 of  an	 instruction  or  data	to  be	acted	on.
		 Relocatable   operands,   unlike   direct   memory
		 operands, are relative	to the start of	the segment
		 or  group  in which the symbol	is defined and have
		 no explicit  value  until  the	 program  has  been
		 linked.

		 Examples

		      call    main		  mov	  bx, local
		      mov     bx, offset DGROUP:table



		 5.2.4	Location Counter


		      $

		 The location counter is a  special  operand  that,
		 during	 assembly,  represents the current location
		 within	the current segment.  The location  counter
		 has  the  same	 attributes  as	 a  near label.	 It
		 represents an instruction address that	is relative
		 to  the  current  segment.  Its offset	is equal to
		 the number of bytes that have been  generated	for
		 that  segment to that point.  After each statement
		 in the	segment	has been assembled,  the  assembler
		 increments  the  offset  by  the  number  of bytes
		 generated.

		 Example



								5-3


















	      XENIX Macro Assembler Reference Manual



		   target  equ	   $		   mov	   ax, 1
			   .		     .		       .
			   jmp	   target



	      5.2.5  Register Operands

	      Syntax

		   reg-name

	      A	register operand is the	name of	a CPU  register.
	      Register operands	direct instructions to carry out
	      actions on the contents of  the  given  registers.
	      The reg-name can be any one of the following:

		   ax	   ah	   al	   bx	   bh	   bl
		   cx	   ch	   cl	   dx	   dh	   dl
		   cs	   ds	   ss	   es	   sp	   bp
		   di	   si

	      Any combination of upper and lower case letters is
	      allowed.

	      The ax,  bx,  cx,	 and  dx  registers  are  16-bit
	      general  purpose	registers.  They can be	used for
	      any data or numeric manipulation.	 The ah, bh, ch,
	      dh  registers  represent	the  high  8-bits of the
	      corresponding    general	  purpose     registers.
	      Similarly,  al,  bl, cl, and dl represent	the low-
	      order 8-bits of the general purpose registers.

	      The cs, ds, ss, and es registers are  the	 segment
	      registers.    They  contain  the	current	 segment
	      address  of  the	code,  data,  stack,  and  extra
	      segments,	 respectively.	All instruction	and data
	      addresses	are relative to	the segment  address  in
	      one of these registers.



	      5-4



















					   Operands and	Expressions



		 The  sp  register  is	the  16-bit  stack  pointer
		 register.   The stack pointer contains	the current
		 top of	stack address.	This address is	relative to
		 the  segment  address	in  the	 ss register and is
		 automatically modified	by instructions	that access
		 the stack.

		 The bx, bp, di, and si	registers are  16-bit  base
		 and  index  registers.	  These	are general purpose
		 registers that	are typically used for pointers	 to
		 program data.

		 The 16-bit flag register contains nine	1-bit flags
		 whose	positions  and	meaning	 are defined in	the
		 following table:
			 __________________________________
			 |Flag Bit   Meaning		   |
			 |_________________________________|
			 |   0	     carry flag		   |
			 |   2	     parity flag	   |
			 |   4	     auxiliary flag	   |
			 |   5	     trap flag		   |
			 |   6	     zero flag		   |
			 |   7	     sign flag		   |
			 |   9	     interrupt-enable flag |
			 |   10	     direction flag	   |
			 |_________________________________|

		 Although  no  name  exists  for  the  16-bit  flag
		 register,  the	 contents  of  the  register can be
		 accessed using	the LAHF,  SAHF,  PUSHF,  and  POPF
		 instructions.


		 5.2.6	Based Operands

		 Syntax





								5-5



















	      XENIX Macro Assembler Reference Manual



		   disp[ bp ]	   disp[ bx ]

	      A	 based	operand	 represents  a	memory	 address
	      relative	to  one	of the base registers: bp or bx.
	      The disp can be any  immediate  or  direct  memory
	      operand.	 It  must evaluate to an absolute number
	      or memory	address.   If no disp is given,	zero  is
	      assumed.

	      The effective address of a based	operand	 is  the
	      sum  of  the  disp  value	 and the contents of the
	      given register.  If  bp  is  used,  the  operand's
	      address  is  relative to the segment pointed to by
	      the ss register.	If bx is used,	the  address  is
	      relative	to  the	 segment  pointed  to  by the ds
	      register.

	      Based operands have a variety of alternate  forms.
	      The following illustrate a few of	these forms:

		   [disp][bp]	    [bp	+ disp]	       [bp].disp
		   [bp]+disp

	      In each case, the	effective address is the sum  of
	      disp and the contents of the given register.

	      Examples

		   mov	ax, [ bp ]		 mov  ax, [ bx ]
		   mov	ax, 12[	bx ]	  mov  ax, fred[ bp ]



	      5.2.7  Indexed Operands

	      Syntax

		   disp[ si ]	   disp[ di ]

	      An indexed operand  represents  a	 memory	 address



	      5-6


















					   Operands and	Expressions



		 that is relative to one of the	index registers: si
		 or di.	 The disp can be any  immediate	 or  direct
		 memory	 operand.   It must evaluate to	an absolute
		 number	or memory address.   If	no disp	 is  given,
		 zero is assumed.

		 The effective address of an indexed operand is	the
		 sum  of  the  disp  value  and	the contents of	the
		 given register.  The address is always	relative to
		 the segment pointed to	by the ds register.

		 Indexed  operands  have  a  variety  of  alternate
		 forms.	  The  following  illustrate a few of these
		 forms:

		      [disp][di]       [di + disp]	  [di].disp
		      [di]+disp

		 In each case, the effective address is	the sum	 of
		 disp and the contents of the given register.

		 Examples

		      mov  ax, [ si ]		    mov	 ax, [ di ]
		      mov  ax, 12[ di ]	     mov  ax, fred[ si ]



		 5.2.8	Based Indexed Operands

		 Syntax

		      disp[ bp ][ si ]		   disp[ bp ][ di ]
		      disp[ bx ][ si ]	    disp[ bx ][	di ]

		 A  based  indexed  operand  represents	 a   memory
		 address  that is relative to a	combination of base
		 and  index  registers.	  The  disp  can   be	any
		 immediate  or	direct	memory	operand.   It  must
		 evaluate to an	absolute number	or memory  address.



								5-7


















	      XENIX Macro Assembler Reference Manual



	      If no disp is given, zero	is assumed.

	      The effective address of a based	indexed	 operand
	      is  the  sum of the disp value and the contents of
	      the given	registers.  If the bp register is  used,
	      the  address is relative to the segment pointed to
	      by the ss	register.   Otherwise,	the  address  is
	      relative	to  the	 segment  pointed  to  by the ds
	      register.

	      Based indexed operands have a variety of alternate
	      forms.   The  following  illustrate a few	of these
	      forms:

		   [disp][bp][di]		    [bp+di+disp]
		   [bp+di].disp	     [di]+disp+[bp]

	      In each case, the	effective address is the sum  of
	      disp and the contents of the given registers.

	      Examples

		   mov	ax, [ bp ][ si ]
		   mov	ax, [ bx + di ]
		   mov	ax, 12[	bp + di	]
		   mov	ax, fred[ bx ][	si ]



	      5.2.9  Structure Operands

	      Syntax

		   variable.field

	      A	structure operand represents the memory	 address
	      of  one  member of a structure.  The variable must
	      be the name of a structure or  must  be  a  memory
	      operand	that   resolves	 to  the  address  of  a
	      structure, and field must	be the name of	a  field



	      5-8


















					   Operands and	Expressions



		 within	that structure.

		 The effective address of a  structure	operand	 is
		 the sum of the	offsets	of variable and	field.	The
		 address is relative to	the  segment  or  group	 in
		 which the variable is defined.

		 In the	 following  examples,  ``current_date''	 is
		 assumed   to  be  the	structure  defined  by	the
		 following:

		      date struc		    month     dw  ?
			   day	dw  ?			 year dw  ?
		      date ends
		      current_date  date <'ja','01','84'>

		 Example

		      mov  ax, current_date.day
		      mov  current_date.year, '85'

		 Structure operands are	often used to access values
		 on  the stack.	  One method is	to copy	the current
		 stack address into the	bp register, then  use	``[
		 bp  ].member''	 to  access  elements on the stack.
		 This  method  makes  all  values  on	the   stack
		 available in any desired format.


		 5.2.10	 Record	Operands

		 Syntax

		      recordname < [value],,, >

		 A record operand refers to the	value of  a  record
		 type.	 The  operands	can be in expressions.	The
		 recordname must be  the  name	of  a  record  type
		 defined in the	source file.  The optional value is
		 the value of a	field in the record.  If more  than



								5-9


















	      XENIX Macro Assembler Reference Manual



	      one  value  is given, the	values must be separated
	      by  commas.   The	 enclosing  angle  brackets  are
	      required,	 even if no value is given.  If	no value
	      for a field is given, the	default	value  for  that
	      field is used.

	      Examples

		   mov	ax, encode <1,3,2>
		   mov	cx, key	<,7>



	      5.2.11  Record Field Operands

	      Syntax

		   record-fieldname

	      The record field operand represents  the	location
	      of  a  field  in	its  corresponding  record.  The
	      operand evaluates	to the bit position of the  low-
	      order  bit  in  the  field  and  can  be used as a
	      constant operand.

	      The  record-fieldname  must  be  the  name  of   a
	      previously defined record	field.	In the following
	      examples,	 assume	 that  the  record  ``rec1''  is
	      defined as:

		   rtype     RECORD    field1:3,field2:6,field3:7
		   rec1	rtype	  < >


	      Example

		   mov	ax, field1

	      This  example  copies  13,  the  shift  count  for
	      field1, to ax.



	      5-10


















					   Operands and	Expressions



		      mov  dx,rec1		     mov  cl,field2
		      shr  dx,cl

		 This example copies 7,	the shift count	for field2,
		 to  cl,  then uses the	address	of ``rec1,'' copied
		 to dx,	 in  a	shift  operation.   This  operation
		 adjusts  rec1	so that	field2 is now at the lowest
		 bit.


		 5.3  Expressions

		 An expression is a  combination  of  operands	and
		 operators   that  evaluates  to  a  single  value.
		 Operands in expressions can be	any of the operands
		 described  in	this  chapter.	 The  result  of an
		 expression can	be a value or  a  memory  location,
		 depending  on	the types of operands and operators
		 used.

		 MASM provides a variety of operators.	Arithmetic,
		 shift,	   relational,	  and	bitwise	  operators
		 manipulate and	compare	 the  values  of  operands.
		 Attribute  operators  manipulate the attributes of
		 operands, such	as their type, address,	and size.

		 The following sections	describe the  operators	 in
		 detail.   The	attribute  operators  are described
		 individually.


		 5.3.1	Arithmetic Operators

		 Syntax








							       5-11



















	      XENIX Macro Assembler Reference Manual



		   exp1	  *   exp2		 exp1	/   exp2
		   exp1	  MOD	exp2		 exp1	+   exp2
		   exp1	  -   exp2	+ exp	   - exp

	      Arithmetic   operators	provide	   the	  common
	      mathematical  operations.	  The operators	have the
	      following	meanings:
	       ________________________________________________
	       |Operator   Meaning			       |
	       |_______________________________________________|
	       |   *	   Multiplication.		       |
	       |   /	   Integer division.		       |
	       |  MOD	   Remainder after division (modulus). |
	       |   +	   Addition.			       |
	       |   -	   Subtraction.			       |
	       |   +	   Positive (unary).		       |
	       |_______________________________________________|

	      For all arithmetic operators except + and	 -,  the
	      expressions exp1 and exp2	must be	integer	numbers.
	      The + operator can  be  used  to	add  an	 integer
	      number  to  a  relocatable  memory  operand. The -
	      operator can be used to subtract an integer number
	      from a relocatable memory	operand.  The -	operator
	      can also	be  used  to  subtract	one  relocatable
	      operand  from  another,  but  only if the	operands
	      refer to locations within	the same  segment.   The
	      result is	an absolute value.

	      Examples












	      5-12



















					   Operands and	Expressions



		      14  *  4	     ; equals  56
		      14  /  4	     ; equals  3
		      14  MOD  4     ; equals  2
		      14  +  4	     ; equals  18
		      14  -
		   4	   ; equals  10
		      14  -
		   +4	   ; equals  10
		      14  -  -
		 4	; equals  18
		      alpha + 5	     ; add 5 to	alpha's	offset
		      alpha -
		  5	 ; subtract 5 from alpha's offset
		      alpha -
		  beta	 ; subtract beta's offset from alpha's




		 5.3.2	SHR and	SHL Operators

		 Syntax

		      expression SHR count
		      expression SHL count

		 The  SHR  and	SHL  operators	shift	the   given
		 expression  right or left by count number of bits.
		 Bits shifted off the end  of  the  expression	are
		 lost.	 If  count  is greater than or equal to	16,
		 the result is 0.











							       5-13



















	      XENIX Macro Assembler Reference Manual



	      Examples

		   01110111B SHL 3	    ; equals 10111000B
		   01110111B SHR 3	    ; equals 00001110B



	      5.3.3  Relational	Operators

	      Syntax

		   exp1	  EQ   exp2		exp1   NE   exp2
		   exp1	  LT   exp2		exp1   LE   exp2
		   exp1	  GT   exp2	 exp1	GE   exp2

	      The relational operators compare	the  expressions
	      exp1  and	 exp2  and  return  true (0FFFFH) if the
	      given condition is satisfied, or false (0000H)  if
	      it  is  not.   The  expressions  must  resolve  to
	      absolute values.	The operators have the following
	      meanings:
	      ____________________________________________________________
	      |Operator	  Condition is satisfied when:			  |
	      |___________________________________________________________|
	      |EQ	  Operands are equal.				  |
	      |NE	  Operands are not equal.			  |
	      |LT	  Left operand is less than right.		  |
	      |LE	  Left operand is less than or equal to	right.	  |
	      |GT	  Left operand is greater than right.		  |
	      |___________________________________________________________|

	      Relational  operators  are  typically  used   with
	      conditional     directives     and     conditional
	      instructions to direct program control.

	      Examples






	      5-14



















					   Operands and	Expressions



		      1	  EQ   0	  ; false
		      1	  NE   0	  ; true
		      1	  LT   0	  ; false
		      1	  LE   0	  ; false
		      1	  GT   0	  ; true
		      1	  GE   0	  ; true



		 5.3.4	Bitwise	Operators

		 Syntax

		      NOT   exp			  exp1	 AND   exp2
		      exp1   OR	  exp2	    exp1   XOR	 exp2

		 The logical operators perform	bitwise	 operations
		 on the	given expressions.  In a bitwise operation,
		 the operation is  performed  on  each	bit  in	 an
		 expression  rather  than  on  the  expression as a
		 whole.	 The expressions must resolve  to  absolute
		 values.

		 The operators have the	following meanings:
			 __________________________________
			 |Operator   Meaning		   |
			 |_________________________________|
			 |NOT	     Inverse.		   |
			 |AND	     Boolean AND.	   |
			 |OR	     Boolean OR.	   |
			 |_________________________________|

		 Examples

		      NOT   11110000B	       ; equals	00001111B
		      01010101B	  AND	11110000B   ; equals 01010000B
		      01010101B	  OR	11110000B   ; equals 11110101B
		      01010101B	  XOR	11110000B   ; equals 10100101B




							       5-15



















	      XENIX Macro Assembler Reference Manual





	      5.3.5  Index Operator

	      Syntax

		   expression1	[ expression2 ]

	      The  index  operator,  [	],  adds  the  value  of
	      expression1  to  expression2.   This  operator  is
	      identical	 to  the   +   operator,   except   that
	      expression1 is optional.

	      If  expression1  is  given,  the	expression  must
	      appear to	the left of the	operator.  It can be any
	      integer value,  absolute	symbol,	 or  relocatable
	      operand.	 If no expression1 is given, the integer
	      value,  0,  is  assumed.	 If  expression1  is   a
	      relocatable   operand,   expression2  must  be  an
	      integer  value  or  absolute  symbol.   Otherwise,
	      expression2  can	be  any	 integer value,	absolute
	      symbol, or relocatable operand.

	      The index	operator  is  typically	 used  to  index
	      elements	 of   an   array,   such  as  individual
	      characters in a character	string.

	      Examples

		   mov	al, string[3]	       mov  ax,	array[4]
		   mov	string[LAST], al
		   mov	cx, DGROUP:[1]

	      Note that	the last example  is  identical	 to  the
	      statement	``mov	cx, DGROUP:1.''







	      5-16



















					   Operands and	Expressions



		 5.3.6	PTR Operator

		 Syntax

		      type PTR expression

		 The PTR operator  forces  the	variable  or  label
		 given	by  the	 expression  to	 be  treated  as  a
		 variable or label having the type given  by  type.
		 The  type  must  be  one of the following names or
		 values:

		      BYTE	1      WORD	 2	DWORD	  4
		      QWORD	8		  TBYTE		 10
		      NEAR	0FFFFh	    FAR	      0FFFEh

		 The expression	can  be	 any  operand.	 The  BYTE,
		 WORD,	and  DWORD  types  can	be used	with memory
		 operands only.	 The NEAR and FAR types	can be used
		 with labels only.

		 The PTR operator is typically	used  with  forward
		 references  to	 explicitly  define  what  size	 or
		 distance a  reference	has.   If  not	used,  MASM
		 assumes   a  default  size  or	 distance  for	the
		 reference. The	PTR operator is	also used  to  give
		 instructions  access  to  variables  in  ways that
		 would	otherwise  generate  errors,  for  example,
		 accessing  the	 high-order  byte  of  a  WORD size
		 variable.

		 Examples

		      call far ptr subrout3
		      mov  byte	ptr [array], 1
		      add  al, byte ptr	[full_word]






							       5-17



















	      XENIX Macro Assembler Reference Manual



	      5.3.7  Segment Override Operator

	      Syntax

		   segment-register : expression	segment-
	      name : expression	     group-name	: expression

	      The  segment  override  operator	(:)  forces  the
	      address  of  a  given  variable  or  label  to  be
	      computed	using  the  beginning	of   the   given
	      segment-register,	segment-name, or group-name.  If
	      a	segment-name or	group-name is  given,  the  name
	      must have	been assigned to a segment register with
	      a	previous ASSUME	directive and  defined	using  a
	      SEGMENT or GROUP directive.  The expression can be
	      an absolute symbol  or  relocatable  operand.  The
	      segment-register must be one of CS, DS, SS, or ES.

	      By default, the  effective  address  of  a  memory
	      operand  is computed relative to the DS, SS, or ES
	      register,	depending on the instruction and operand
	      type.  Similarly,	 all  labels  are  assumed to be
	      NEAR.  These default types can be	overridden using
	      the segment override operator.

	      Examples

		   mov	ax, es:[bx][si]
		   mov	_TEXT:far_label, ax
		   mov	ax, DGROUP:variable
		   mov	al, cs:0001H



	      5.3.8  SHORT Operator

	      Syntax

		   SHORT label



	      5-18



















					   Operands and	Expressions



		 The SHORT operator sets  the  type  of	 the  given
		 label	to  SHORT.   Short  labels  can	 be used in
		 ``jump'' instructions whenever	the  distance  from
		 the  label to the instruction is not more than	127
		 bytes.	 Instructions using short  labels  are	one
		 byte  smaller	than  identical	 instructions using
		 near labels.

		 Example

		      jmp  short repeat



		 5.3.9	THIS Operator

		 Syntax

		      THIS type

		 The THIS operator creates an operand whose  offset
		 and   segment	value  are  equal  to  the  current
		 location counter value	and whose type is given	 by
		 type.	The type can be	any one	of the following:

		      NEAR	     FAR	BYTE	       WORD
		      DWORD	     QWORD	TBYTE

		 The THIS operator is typically	used with  the	EQU
		 or  =	directive  to  create labels and variables.
		 This is similar to using the  LABEL  directive	 to
		 create	labels and variables.

		 Examples

		      tag  equ	this byte

		 This example is equivalent to the statement  ``TAG
		 LABEL	BYTE''.



							       5-19



















	      XENIX Macro Assembler Reference Manual



		   check     =	  this near

	      This  example  is	 equivalent  to	 the   statement
	      ``CHECK  LABEL  NEAR''.


	      5.3.10  HIGH and LOW Operators

	      Syntax

		   HIGH	expression	LOW expression

	      The HIGH and LOW operators return	the high and low
	      8	bits of	the given expression.  The HIGH	operator
	      returns the high 8 bits of the expression; the LOW
	      operator	 returns  the  low-order  8  bits.   The
	      expression can be	any value.

	      Examples

		   mov	ah, high word_value
		   mov	al, low	0FFFFH



	      5.3.11  SEG Operator

	      Syntax

		   SEG expression

	      The SEG operator returns the segment value of  the
	      given  expression.   The	expression  can	 be  any
	      label, variable,	segment	 name,	group  name,  or
	      other symbol.

	      Example





	      5-20



















					   Operands and	Expressions



		      mov  ax, seg variable_name
		      mov  ax, seg label_name



		 5.3.12	 OFFSET	Operator

		 Syntax

		      OFFSET expression

		 The OFFSET operator  returns  the  offset  of	the
		 given	expression.   The  expression  can  be	any
		 label,	variable, segment name,	 or  other  symbol.
		 The  returned value is	the number of bytes between
		 the item and the beginning of the segment in which
		 it  is	 defined.   For	 a segment name, the return
		 value is the offset from the start of the  segment
		 to   the  most	 recent	 byte  generated  for  that
		 segment.

		 The segment override operator (:) can be  used	 to
		 force OFFSET to return	the number of bytes between
		 the item in the expression and	the beginning of  a
		 named	segment	 or group.  This is the	method used
		 to generate valid offsets for items  in  a  group.
		 See the second	example	below.

		 Examples

		      mov  bx, offset subrout3
		      mov  bx, offset DGROUP:array

		 The returned value is always a	relative value that
		 is  subject  to  change  by  the  linker  when	the
		 program is actually linked.






							       5-21



















	      XENIX Macro Assembler Reference Manual



	      5.3.13  TYPE Operator

	      Syntax

		   TYPE	expression

	      The TYPE operator	returns	 a  number  representing
	      the   type   of  the  given  expression.	 If  the
	      expression is a variable,	the operator returns the
	      size of the operand in bytes. If the expression is
	      a	label, the operator returns 0FFFFH if the  label
	      is  NEAR,	 and  0FFFEH  if the label is FAR.  Note
	      that the return value can	be used	to  specify  the
	      type  for	 a PTR operator.  See the second example
	      below.

	      Examples

		   mov	ax, type array
		   jmp	(type get_loc) ptr destiny



	      5.3.14  .TYPE Operator

	      Syntax

		   .TYPE expression

	      The .TYPE	operator returns a byte	that defines the
	      mode  and	 scope	of the given expression.  If the
	      expression is not	valid, .TYPE returns zero.

	      The variable's attributes	are returned in	bits  0,
	      1, 5, and	7 as follows:







	      5-22



















					   Operands and	Expressions


		 ___________________________________________________
		 |Bit Position	 If Bit=0	    If Bit=1	    |
		 |     0	 Absolute	    Program related |
		 |     1	 Not Data related   Data related    |
		 |     5	 Not defined	    Defined	    |
		 |     7	 Local scope	    External scope  |
		 |__________________________________________________|

		 If both the scope bit and defined  bit	 are  zero,
		 the expression	is not valid.
		 The  .TYPE  operator  is   typically	used   with
		 conditional directives, where an argument may need
		 to be tested to make a	decision regarding  program
		 flow.

		 Example

		      x	   db	12	z    equ  .type	x

		 This example sets z to	34.


		 5.3.15	 LENGTH	Operator

		 Syntax

		      LENGTH variable

		 The LENGTH operator returns the  number  of  BYTE,
		 WORD, DWORD, QWORD, or	TBYTE elements in the given
		 variable.  The	size of	each element depends on	the
		 variable's defined type.

		 Only variables	that have been	defined	 using	the
		 DUP operator return values greater than one.	The
		 return	value is always	the  number  that  precedes
		 the first DUP operator.

		 In the	following examples, assume the definitions:




							       5-23



















	      XENIX Macro Assembler Reference Manual



		   array      dw  100	dup(1)
		   table      dw  100	dup(1,10 dup(?))

	      Examples

		   mov	cx, length array

	      In this example, LENGTH returns 100.

		   mov	cx, length table

	      In this example, LENGTH returns  100.  The  return
	      value does not depend on any nested DUP operators.


	      5.3.16  SIZE Operator

	      Syntax

		   SIZE	variable

	      The SIZE operator	 returns  the  total  number  of
	      bytes  allocated	for  the  given	 variable.   The
	      return value is  equal  to  the  return  value  of
	      LENGTH times the return value of TYPE.

	      In the following example,	assume the definition:

		   array     dw	  100	 dup(1)

	      Example

		   mov	bx, size array

	      In this example, SIZE returns 200.







	      5-24



















					   Operands and	Expressions



		 5.3.17	 WIDTH Operator

		 Syntax

		      WIDTH  record-fieldname |	record

		 The WIDTH operator returns the	width (in bits)	 of
		 the  given  record  field  or	record.	The record-
		 fieldname must	be the name of a record	defined	 in
		 a field.  The record must be the name of a record.

		 In the	following examples, assume that	the  record
		 ``rec1'' is defined as:

		      rtype	RECORD	  field1:3,field2:6,field3:7
		      rec1 rtype   <>


		 Example

		      WIDTH field1   ;equals 3
		      WIDTH field2   ;equals 6
		      WIDTH field3   ;equals 7
		      WIDTH rtype    ;equals 16



		 5.3.18	 MASK Operator

		 Syntax

		      MASK  record-fieldname | record

		 The MASK operator returns a bit mask for  the	bit
		 positions in a	record occupied	by the given record
		 field.	 A bit in the mask contains a 1	if that	bit
		 corresponds  to  a  record  bit.   All	 other bits
		 contain 0.  The record-fieldname must be the  name
		 of a record field.



							       5-25



















	      XENIX Macro Assembler Reference Manual



	      In the following examples, assume	that the  record
	      ``rec1'' is defined as:

		   rtype     RECORD    field1:3,field2:6,field3:7
		   rec1	rtype	<>


	      Example

		   MASK	field1	  ;equals E000H
		   MASK	field2	  ;equals 1F80H
		   MASK	field3	  ;equals 003FH
		   MASK	rtype	  ;equals 0FFFFH



	      5.3.19  Expression Evaluation and	Precedence

	      Expressions are evaluated	according to  the  rules
	      of  operator  precedence and order.  Operations of
	      highest	precedence    are    performed	  first.
	      Operations  of equal precedence are performed from
	      left to right.  This default order  of  evaluation
	      can  be  overridden  using  enclosing parentheses.
	      Operations in  parentheses  are  always  performed
	      before  any  adjacent  operations.   The following
	      table  lists  the	 precedence  of	 all  operators.
	      Operators	on the same line have equal precedence.














	      5-26



















					   Operands and	Expressions


		    ___________________________________________
		    |Precedence	  Operators		       |
		    |__________________________________________|
		    |Highest				       |
		    |1		  LENGTH, SIZE,	WIDTH, MASK    |
		    |2		  ( )			       |
		    |3		  [ ]			       |
		    |4		  :			       |
		    |5		  PTR, OFFSET, SEG, TYPE, THIS |
		    |6		  HIGH,	LOW		       |
		    |7		  *, /,	MOD, SHL, SHR	       |
		    |8		  +, -			       |
		    |9		  EQ, NE, LT, LE, GT, GE       |
		    |10		  NOT			       |
		    |11		  AND			       |
		    |12		  OR, XOR		       |
		    |13		  SHORT, .TYPE		       |
		    |__________________________________________|


		 Examples

		      8	/ 4 * 2		  ; equals 4
		      8	/ (4 * 2)	  ; equals 1
		      8	+ 4 * 2		  ; equals 16
		      (8 + 4) *	2	  ; equals 24
		      8	EQ 4 AND 2 LT 3	  ; equals 0000H (false)
		      8	EQ 4 OR	2 LT 3	  ; equals 0FFFFH (true)



		 5.4  Forward References

		 Although  MASM	 permits  forward   references	 to
		 labels,  variable  names, segment names, and other
		 symbols, such	references  can	 lead  to  assembly
		 errors	 if not	used properly.	A forward reference
		 is any	use of a name before it	has  been  formally
		 declared.   For  example,  in	the JMP	instruction
		 below,	 the  label   ``target''   is	a   forward



							       5-27



















	      XENIX Macro Assembler Reference Manual



	      reference.

			jmp  target		      mov  ax, 0
		   target:

	      Whenever MASM encounters an undefined name in pass
	      1,   it	assumes	 that  the  name  is  a	 forward
	      reference.  If only a name is given,   MASM  makes
	      assumptions  about  that	name's	type and segment
	      register,	and uses these assumptions  to	generate
	      code  or	data for the statement.	 For example, in
	      the  JMP	instruction  above,  MASM  assumes  that
	      ``target''  is  an  instruction  label having NEAR
	      type.  It	generates  three  bytes	 of  instruction
	      code for the instruction.

	      MASM  bases  its	assumptions  on	 the   statement
	      containing  the  forward	reference.   Errors  can
	      occur when these assumptions are	incorrect.   For
	      example, if ``target'' were really a FAR label and
	      not a NEAR label,	the assumption made by	MASM  in
	      pass 1 would cause a phase error.	 In other words,
	      MASM would generate five bytes of	instruction code
	      for  the	JMP instruction	in pass	2 but only three
	      in pass 1.

	      To  avoid	 errors	 with  forward	references,  the
	      segment  override	 (:),  PTR,  and SHORT operators
	      should be	used to	override the assumptions made by
	      MASM whenever necessary.	The following guidelines
	      list when	these operators	should be used.

	      If a forward  reference  is  a  variable	that  is
	      relative	to  the	ES, SS,	or CS register,	then use
	      the segment override operator (:)	to  specify  the
	      variable's segment register, segment, or group.

	      Examples




	      5-28



















					   Operands and	Expressions



		      mov  ax, ss:stacktop	  inc  data:time[1]
		      add  ax, dgroup:_I

		 If the	segment	override operator is not used, MASM
		 assumes that the variable is DS relative.

		 If a forward reference	is an instruction label	 in
		 a  JMP	instruction, then use the SHORT	operator if
		 the instruction is less than 128  bytes  from	the
		 point of reference.

		 Example

		      jmp  short target

		 If SHORT  is  not  used,  MASM	 assumes  that	the
		 instruction  is greater than 128 bytes	away.  This
		 does not cause	an error, but it does cause MASM to
		 generate  an  extra  NOP  instruction	that is	not
		 needed.

		 If a forward reference	is an instruction label	 in
		 a  CALL  or  JMP  instruction,	 then  use  the	PTR
		 operator to specify the label's type.

		 Examples

		      call far ptr print      jmp  near	ptr exit

		 MASM assumes that the label has NEAR type, so	PTR
		 need  not  be	used for NEAR labels.  If the label
		 has FAR type, however,	and  PTR  is  not  used,  a
		 phase error will result.

		 If the	forward	reference is a segment name with  a
		 segment override operator, use	the GROUP statement
		 to associate the segment name with a  group  name,
		 then  use  the	 ASSUME	 statement to associate	the
		 group name with a segment register.



							       5-29



















	      XENIX Macro Assembler Reference Manual



	      Example

		   dgroup    segment stack
			assume	  ss: dgroup

		   code	segment		      .		       .
			.		 mov  ax, stack:stacktop
			.	     .		  .

	      If you do	not associate a	group with  the	 segment
	      name, MASM may ignore the	segment	override and use
	      the default segment  register  for  the  variable.
	      This usually results in a	phase error in pass 2.


	      5.5  Strong Typing for Memory Operands

	      MASM carries out	strict	syntax	checks	for  all
	      instruction  statements,	including  strong typing
	      for operands that	refer to memory	locations.  This
	      means  that  any	relocatable  operand  used in an
	      instruction that operates	on an implied data  type
	      must  either  have  that type, or	have an	explicit
	      type override (PTR operator).

	      For example, in the following program segment, the
	      variable ``string'' is incorrectly used in an move
	      instruction.

		   string    db	  "A message."

			mov  ax, string[1]

	      This statement will create an ``Operand types must
	      match''  error  since ``string'' has BYTE	type and
	      the instruction expects  a  variable  having  WORD
	      type.

	      To avoid this error, the PTR operator must be used
	      to override the variable's type.	The statement



	      5-30


















					   Operands and	Expressions



			   mov	ax, WORD PTR string[1]

		 will assemble correctly and execute as	expected.







































							       5-31























	      Chapter 5


	      Operands and Expressions
	      __________________________________________________



	      5.1  Introduction	 5-1

	      5.2  Operands  5-1
		   5.2.1  Constant Operands  5-2
		   5.2.2  Direct Memory	Operands  5-2
		   5.2.3  Relocatable Operands	5-3
		   5.2.4  Location Counter  5-3
		   5.2.5  Register Operands  5-4
		   5.2.6  Based	Operands  5-6
		   5.2.7  Indexed Operands  5-7
		   5.2.8  Based	Indexed	Operands  5-8
		   5.2.9  Structure Operands  5-9
		   5.2.10 Record Operands  5-10
		   5.2.11 Record Field Operands	 5-10

	      5.3  Expressions	5-11
		   5.3.1  Arithmetic Operators	5-12
		   5.3.2  SHR and SHL Operators	 5-13
		   5.3.3  Relational Operators	5-14
		   5.3.4  Bitwise Operators  5-15
		   5.3.5  Index	Operator  5-16
		   5.3.6  PTR Operator	5-17
		   5.3.7  Segment Override Operator  5-18
		   5.3.8  SHORT	Operator  5-19
		   5.3.9  THIS Operator	 5-19
		   5.3.10 HIGH and LOW Operators  5-20
		   5.3.11 SEG Operator	5-20
		   5.3.12 OFFSET Operator  5-21
		   5.3.13 TYPE Operator	 5-22
		   5.3.14 .TYPE	Operator  5-22
		   5.3.15 LENGTH Operator  5-23
		   5.3.16 SIZE Operator	 5-24


























		      5.3.17 WIDTH Operator  5-25
		      5.3.18 MASK Operator  5-26
		      5.3.19 Expression	Evaluation and
		             Precedence  5-26

		 5.4  Forward References  5-27

		 5.5  Strong Typing for	Memory Operands	 5-30
















































