Assembly Language : Directives

As mentioned previously, assembler directives are instructions to the assembler, and are not translated into machine instructions.

The use of directives gives the programmer some control over the operation of the assembler, increasing flexibility in the way programs are written. The following is a list of the common pseudo-ops.

  • EQUATE

    is used to make programs easier to write. The EQU directive creates absolute symbols and aliases by assigning an expression or value to the declared variable
    name. Its format is, name: EQU expression Consider the following statement.

  • NUMBER1: EQU 36H

    The assembler will replace every occurrence of the label NUMBER1 with the value its been equated to, ie, 36 hexadecimal. The statement

    LDAA #NUMBER1

    will be interpreted by the assembler as

    LDAA #36H

    An absolute symbol represents a 16bit value; an alias is a name that represents another symbol. The declared name must be unique, one that has not been previously declared. The redefining of a previous symbol is normally not allowed.

    NUM1: EQU 20H

    … …

    NUM1: EQU 30H ; error

  • ORIGIN

    This specifies the address to be used for the generation of code. Subsequent instructions and data address’s begin at the new value. Normally, it is used to set the start address of the program, but can also set the location counter to the value specified.

  • ORG 120H
    LDAA #FFH

    The statement LDAA #FFH begins at byte 120h.

    ORG $ + 2

    start: LDAA #34H

    The instruction associated with the label start is declared to start at the address 2bytes beyond the current value of the location counter (specified by $).

  • CPU TYPES

    This directive is used by multi-purpose assemblers to specify which target processor is being used. The format for CRS8 is CPU cpuname where cpuname consists of a valid processor name, eg CPU 6802This directive appears before any machine instructions.

  • OUTPUT FORMATS

    This directive is used to select the output format for the generated machine  instructions. Several output formats are available for downloading into EPROM or a
    target system.

  • HOF recordtypewhere recordtype is one of the following

    MOT ; motorola formats

    INT ; intel formats

    TEK ; tektronix formats

    This directive appears before any machine
    instructions.

  • BYTE STORAGE

    The directive used to allocate and initialize bytes (8bits) of storage is DFB definebyteIts format is,

    name: DFB initialvalue,,,

    The name portion is optional. Consider the following examples for CRS8.

    value1: DFB 16

    form: DFB 6*2

    text: DFB “Enter your name: ”

    In the first example, the label value1 is assigned a single byte of storage, which is initialized to 16 decimal.The second example allocates a single byte of storage for the label form, and initializes it equal to 12. The last example allocates 17 bytes of storage for the label text. The first byte will be initialized to E, whilst the last byte is initialized to an ASCII space.

  • WORD STORAGE

    The directive used to allocate and initialize words (two bytes) of memory storage is,DWM define word, most significant byte first

    DWL define word, least significant byte first

    Its format is,

    name: DWM initialvalue,,,

    The name portion is optional.

    DWM 1687H

    mess: DWM ‘ab’

    The first example allocates one word of storage, having the values 16H followed by 87H. The second example defines mess as a word initialized with the character values a followed by b. The b will be placed in the low-order byte, and the a will be placed in the high order byte. If only one character is specified, the high-order byte will contain 0.

    Strings when using the DW directive must not contain more than two characters.

  • DATA STORAGE RESERVATION

    This directive is used to reserve storage for later use.array:
    DFS 100

    This example allocates 100 storage bytes, associating the first byte with the label array. The value of these bytes is indeterminate at this point. The 100 bytes will be allocated relative to the current location counter.

  • END and Optional Start Address

    The END directive specifies the end of the assembly language source listing. It may  be followed by an optional entry address. The optional entry address is used by LOADERS to initialize the Program Counter before running the program. If no entry address is specified, execution will start at the first location allocated by the assembler.END

    In this example, the END directive informs the assembler that there is no more source statements.

    ORG 0100H

    start: LDAA #3FH

    JMP start

    END start

    In this example, the END directive also specifies that the entry point to the program is the label start, whose address is 0100H.


SAMPLE PROGRAM FOR MC6802 USING CRS8

The following source file has been named MC6802.ASM

		 	CPU	6802	; 6802 processor
		 	HOF	MOT 	; Motorola Records 
			ORG	0100H 	; Start of Data
	Source:		DFB	'Hello and Welcome'
	Length:		EQU	$ - Source ;Length of Source
	Destin:		DFS	Length	; Buffer which has same 
					; length as Source
			ORG	0120H	; Start of Code
	Entry:		LDX	#Source	; Point Index Reg to 
					; Source string
			LDAB	#Length	; Number of characters to move
	Loop:		LDAA	0,X
			STAA	Length,X
			INX
			DECB
			BNE	Loop
	Fin:		JMP	Fin
			END	Entry

This program is assembled by typing the following command


	CRS8 MC6802

It is not necessary to type the extension .ASM, and CRS8 will
produce two output files.


 MC6802.PRN 	; a list file showing the code generated
 MC6802.HEX	; the record file for downloading to the 
		; target system or Eprom programmer

The listing file MC6802.PRN looks like

	C:6802.TBL	CPU	6802			; 6802 processor
	C:6802.HEX	HOF	MOT			; Motorola Records

	0100		ORG	0100H 			; Start of Data
	0100 48656C6C6F	Source:	DFB	'Hello and Welcome'
	0011 = 		Length: EQU	$ - Source	; Length of Source
	0111 		Destin:	DFS	Length 		; Buffer which has same
							; length as Source 
	0120 			ORG	0120H 		; Start of Code 
	0120 CE0100 	Entry:	LDX	#Source 	; Point Index Reg to 
							; Source string 
	0123 C611 		LDAB	#Length 	; Number of characters
							; to move 
	0125 A600 	Loop:	LDAA 	0,X
	0127 A711		STAA	Length,X
	0129 08			INX
	012A 5A			DECB
	012B 26F8 		BNE 	Loop 
	012D 7E012D 	Fin: 	JMP 	Fin
	0130 			END 	Entry

The first column is the address, the second the instructions or data, and then the mnemonics and comments. This listing is used by the programmer to verify that the assembler has produced the correct instructions and data at the correct addresses. We
can clearly see that it has correctly interpreted the address of Source in the statement LDX #Source as the bytes CE 0100.

The record format file MC6802.HEX looks like

	S00D0000433A363830322E48455892
	S113010048656C6C6F20616E642057656C636F6D1D
	S10401106585
	S1130120CE0100C611A600A711085A26F87E012D9F
	S9030120DB

The format of a motorola record is

	Digit
	 0,1		Record Type = S0, S1 or S9
	 2,3		Number of bytes in Record which includes the load address and checksum bytes
	 4,5,6,7	Load Address 8 to n-2 Data or coded instructions
	 n-1 to n	Checksum value

	 The S0 record identifies the program name
	 The S1 record identifies the data and coded instructions
	 The S9 record identifies the program entry point
		 eg
		S1 04 0110 65 85
		^  ^   ^   ^  ^checksum
		^  ^   ^   ^   data
		^  ^   ^       load address
		^  ^           number of bytes in record
		^              record type

The file is then downloaded to the target system.


ELEMENTARY DATA TYPES

Most programming languages support data types like characters and integers. At the processor level, some instructions support integer type operations such as multiply or divide (except 6802).The programmer is responsible for keeping track of data types. The processor treats all data the same, and if the program goes astray, can interpret data as instructions and vise versa.

Lets look at how elementary data is represented by the programmer for use in assembly language programs.

  • Characters

    are single eight bit values represented using the ASCII code. Values range from 0 to 127. The statement

    
    	 Letter: DFB 'A'
    

    associates one byte of storage to the variable Letter, initializing it to the ASCII character ‘A’ (41H).

    Character Strings

    are multiple bytes, each byte holding an ASCII character. The statement

    
    	String: DFB 'Hello there.'
    

    allocates 12 bytes of storage space. The variable String has the address of the first byte, which has been allocated the character ‘H’ (48H).

  • Integers

    are stored as 16 bit values (two bytes or one word), and are signed or unsigned. The statement

    
    	Number1: DWM -17D
    

    allocates a word of storage for the variable Number1, initializing the word to -17 decimal. Some processors have different instructions for operations on signed and
    unsigned integers. If the processor cannot handle a 16bit value (ie, has only eight bit registers), software will need to be written to do any comparisons on these types.

  • Character Arrays

    are essentially text strings. Each element of the array has storage space for an ASCII character. Strings in some HLL’s are terminated with an End-Of-String symbol (in C it is ASCII 00h, in PCDOS it is ASCII ‘$’). The following statement

    
    	 Digits: DFS 10
    

    allocates 10 locations for a character based array called Digits. The following code routine initializes the Digits array (each successive element) to the digits 0 to 9.

    	ORG	0120H
    	start:	LDAA	#30H	; ASCII '0'
    		LDAB	#11	; ten digits
    		LDX	#Digits
    	loop:	STAA	0,X
    		INX		; next element
    		INCA		; next digit
    		DECB
    		BNE	loop
    	exit:	....
    
    

Typical Array Operations

The following routines are typical of functions which are performed on character based arrays.

  • Copy

    This copys a source string to a destination area. The declaration of the routines is, copystr( src, dest )where src and dest represent the address of the source and destination strings. Writing this type of routine is ideally suited to a processor which has more than one Index or Base register. The MC6802, having only one Index register, presents a small problem. The following code shows this program implemented for the MC6802.

    		CPU	6802
    		HOF	MOT
    		ORG	100H
    	str1:	DFS	10
    	st1len:	EQU	$ - str1
    	str2:	DFS	10
    
    		ORG 120
    	HSRCINX:DFS	02H		; pointer for src string
    	DSTINX: DFS	02H		; pointer for dest string
    	start:	LDX	#str1 		; store address of str1
    		STX	SRCINX
    		LDX	#str2 		; store address of str2 
    		STX 	DSTINX 
    		jsr 	initstr1 	; initialise str1
    		jsr 	copystr 	; copy str1 to str2
    	exit: 	bra 	exit
    
    	initstr1: LDAA	#41H 		; character 'A' 
    		LDAB 	#11 		; elements 1 - 30 
    		LDX 	#str1 		; point to str1
    	lp1:	STAA	0,X 		; store character 
    		INX			; next element 
    		INCA			; next value 
    		DECB 			; loop around 
    		BNE 	lp1 
    		LDAA 	#00 		; null terminator
    		STAA 	0,X 
    		RTS
    
    	copystr: LDX 	SRCINX 		; pick up source pointer
    	cplp2:	LDAA 	0,X 		; get source character 
    		CMPA 	#00H 		; eostr? 
    		BEQ 	cpstrq		; yes, then exit 
    		INX 			; else inc source pointer 
    		STX 	SRCINX 		; store source ptr 
    		LDX 	DSTINX 		; get destination pointer 
    		STAA 	0,X 		; store character
    		INX 			; inc dest ptr 
    		STX 	DSTINX 		; store dest ptr 
    		LDX 	SRCINX		; reload source pointer 
    		BRA 	cplp2 		; repeat
    	cpstrq:	LDX	DSTINX 		; Null terminate dest str 
    		CLR	00,X 
    		RTS 
    	END start1
    
    
  • String Length

    Returns the length of a terminated string. The following code shows this routine implemented for the MC6802. Strlen is entered with the Index register pointing to the string, and returns the length of the string in the B accumulator.

    		CPU	6802
    		HOF	MOT
    	EOFSTR:	EQU	00H
    		ORG	100H
    	str1:	DFB	'Hello and Welcome.', 00H
    		ORG	120H
    	start:	LDX 	#str1 		; point to string jsr strlen 
    					; find length of str1
    	exit:	bra	exit
    	strlen:	LDAB 	#00 		; character count
    
    	strlp1:	LDAA	0,X 		; read character 
    		CMPA 	#EOFSTR 	; is it end of string 
    		BEQ 	strexit 	; yes, then exit 
    		INX 			; no, inc str ptr 
    		INCB 			; inc character count 
    		BRA	strlp1 		; and repeatstr
    	exit:	RTS 			; acc B has length 
    		END	start2
    
    
  • Search for first occurrence of a character

    This routine returns the address of the specified character found in the string. If the address returned is zero, it indicates the character was not found. The following code shows this routine implemented for the MC6802. Strpos is entered with the Index register pointing to the search string, and the A accumulator with the character search value.

    		CPU	6802
    		HOF	MOT
    	EOFSTR:	EQU	00H
    		ORG	100H
    	str1:	DFB	'Hello and Welcome.', 00H
    		ORG	120H
    	start:	LDAA 	#6FH 		; ASCII 'o'
    		LDX 	#str1 		; point to src string jsr strpos 
    					; find first 'o' in str1
    	exit: 	bra 	exit
    
    	strpos:	CMPA 	0,X 		; is char = search value 
    		BEQ	strex2 		; yes then exit 
    		CMPA 	#EOFSTR 	; is it end of string 
    		BEQ	strex1 		; yes, then exit 
    		INX 			; no, inc str ptr 
    		BRA 	strpos 		; and repeat 
    	strex1:	LDX 	#0000H 		; not found
    	strex2:	RTS 			; Index reg has address 
    		END 	start3
    
    
  • Search for Substring

    This routine is used to find the starting address of a substring within a larger string. It accepts a source string pointer, and a pointer to a substring. It returns the address of the substring, if not found it returns address zero.

  • Substring Insertion/Replacement

    This routine inserts a substring into an existing string.
    Most versions overwrite existing characters. It accepts a pointer to the source string, a pointer to the substring to insert, and a numeric value representing the start position where insertion should begin. No characters should overwrite the end-of-string terminator, or be written to memory locations after the terminator. The routine should return a numeric value representing the number of characters inserted.

  • String Reverse

    This routine reverses the characters in a string. It accepts the address of the string. Hello becomes olleH

  • String to Uppercase

    This routine converts all characters of a string to uppercase. It accepts the address of the string. Hello becomes HELLO

  • String to Lowercase

    This routine converts all characters of a string to lowercase. It accepts the address of the string. Hello becomes hello


ARRAY INDEX CALCULATIONS

This refers to calculating the address of a specified element within an array. In single dimensioned arrays, this is equivalent to


	BASE_ADDRESS + (ELEMENT_NUMBER * NUMBER_OF_BYTES_PER_ELEMENT)

In multi-dimensioned arrays, this is equivalent to


	BASE_ADDRESS + (Col_Num + (Row_num * Num_Col_per_row)) * Num_Bytes_per_Element)


 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s