Assembly Language Programming – Program management tools

These tools are designed to make the process of maintaining programs easier.

MAKE

This utility is designed to ease updating of programs, especially multiple module programs.

It works by using a list of dependencies. These dependencies illustrate the relationship between the source, include, object and executable versions of the program.

The dependencies are stored in a file called makefile.

Consider a program which has the following dependencies.


	 MYDBASE.EXE comprises the modules
		  start.obj
		  search.obj
		  fileio.obj
		  keybdio.obj
		  videoio.obj

Each object file is generated from an assembler source file of the same name.

The command sequence to create the executable program is,


	 tasm start
	 tasm search
	 tasm fileio
	 tasm keybdio
	 tasm videoio
	 tlink start search fileio keybdio videio, mydbase;

The dependencies and command sequences required are entered into the makefile as follows.


	 mydbase.exe: start.obj search.obj fileio.obj keybdio.obj videoio.obj
		  tlink start  search fileio keybdio videio, mydbase;
	 start.obj: start.asm
		  tasm start
	 search.obj: search.asm
		  tasm search
	 fileio.obj: fileio.asm
		  tasm fileio
	 keybdio.obj: keybdio.asm
		  tasm keybdio
	 videoio.obj: videoio.asm
		  tasm videio

The program is assembled and linked by typing


	 make

It works by comparing date and time stamps of the files in each dependency list. Consider the lines


	 keybdio.obj: keybdio.asm
		  tasm keybdio

It compares the date/time stamp of keybdio.asm against keybdio.obj.
If the object file is newer than the assembly file, it will not re-assemble.

If the assembler file has a newer date/time stamp, it will execute the command tasm keybdio to generate a new object file.

The use of make files simplifies the re-assembly by only assembling those files which have been modified.


SOURCE CODE REVISION SYSTEMS

Source code revision systems are used to keep track of different versions of a program. It keeps a record of all the changes made to the program.

Previous revisions can be extracted from the database, and a printout detailing the changes (time, who, line#) can be obtained.


LIBRARY MAINTENANCE

This applies to the maintenance of OBJECT code libraries. An Object code library contains routines which can be reused in any program. The code for the routine is extracted from the library and combined with the users object code at linking time. Users can create their own library routines. The source files are assembled into object code then added to a library.

The following code represents a routine for placement into a Video routines library.


	 TITLE SetCur
	 .CODE
	 PUBLIC setcur
	 
	setcur proc far ; set cursor to position in DX register
		 mov ah, 2 ; dh = y co-ordinate, dl = x co-ordinate
		 xor bh, bh
		 int 10h
		 ret
	setcur endp
	END

After assembling into Object code, the object code is placed into a video library using the TLIB utility.


	TLIB video +setcur.obj

The following source file shows how to use the code in a library.


	 TITLE Libdemo
	 .STACK 200h
	 .CODE
	EXTRN setcur:far
	start: mov dx, 0 ; cursor 0,0
		 call setcur
		 mov ax, 4c00h
		 int 21h
	 END start

After assembling the file Libdemo.asm, the command to link the object and library code together is,


	TLINK  Libdemo,libdemo.exe,libdemo.map, video

LINKERS

The assembler for 8088 PCDOS programs generates object code files. These cannot be executed directly on the computer system, but require further processing in order to generate a runfile. This further process is called the linking phase.

Functions performed by a linker include:

  • combines object modules together
  • combines segments of the same type together
  • resolves addresses unknown at assembly time
  • allocates storage
  • generates symbolic information
  • generates a load module

8088 LINKER OPTIONS

The following options are used to obtain information which is helpful in debugging programs; or generate code for 386 processors.


	 /m add public symbols
	 /x no map file
	 /s map file with segments, publics symbols and start address
	 /t generate .COM file
	 /v add debug info
	 /3 386 code

The Map File Facility

If the linker is requested to generate a map file, it will list the names, load addresses, and lengths of all segments in a program. It also lists the names and load addresses of any groups in the program, the start address, and messages about any errors the linker may have encountered.

The map file generated by the linker for the program DOSCALL.ASM is,


	 Start  Stop   Length Name               Class
	 00000H 00014H 00015H _TEXT              CODE
	 00016H 0002AH 00015H _DATA              DATA
	 00030H 0022FH 00200H STACK              STACK
	  Address         Publics by Name
	  Address         Publics by Value
	Program entry point at 0000:0005


DEFINITION OF LINKING TERMS

  • Relocatable/Relative

    The code generated by the linker is all relative to the location counter. This means that all references to memory is relative to a base/index register, segment register or program counter. This allows the operating system to load the program anywhere in physical memory.

  • Relocatable code is a must for multi-user and multi-tasking operating systems. The program is preceded by a header file, which the operating systems loader uses to perform relocation.
  • Absolute/Fixed

    If the linker generates code which is absolute, all memory references are to absolute addresses, thus the program must reside in a designated memory space. If this space is unavailable, the program cannot be run and must wait.Absolute code is normally used on small single processor systems (ie, CPM), and is not suitable for multi-user environments.

    Absolute code does not contain a header file used for relocation, if a header file exists, it will specify the absolute load address of the code which follows the
    header file.

  • Common

    Variables, labels or symbols may be designated as common. In this way, they are made accessible to those modules which wish to reference them by way of calls or data usage. The common data is shared by the various modules.The linker combines multiple definitions into a single overlayed segment.

  • External/Public

    Public data segments are located in one module but called from another.The Public directive makes the variable, label or symbol in the current segment available to all other modules. It thus transforms locally defined symbols into global symbols.

    The Extern directive makes a global symbols name and type known in a source file so that it may be used/referenced in that file. An extern item is a variable, label or symbol that has been declared using the public directive in another module of the program.

    Example of program using public/extern directives:

    
    	Main Module
    	 NAME    main
    	 .MODEL small
    	 PUBLIC  exit 		;defines exit as being known to other modules
    	 EXTERN   print:near 	;defines print as existing in another module
    	 .STACK 100h
    	 .DATA
    	 .CODE
    	start:	 mov ax, @data 	; Load segment location 
    		 mov ds, ax 	; into DS register
    		 jmp print 	; goto PRINT in other module
    	exit:	 mov ax, 4C00h 	; call terminate function
    		 int 21h
    		 END start
    
    	Task Module
    	 NAME task
    	 .MODEL small
    	 PUBLIC print 		;defines print as public so it can
    	   			;be used by the calling module
    	 EXTERN exit:near 	;defines exit as existing in another module 
    				; outside this one
    	 .DATA
    	string DB "Hello",13,10,"$"
    	 .CODE
    	print:	 mov dx, OFFSET string	;Load location of string
    		 mov  ah, 09h 		;call string display function
    		 int 21h
    		 jmp exit 		;go back to main module
    	 END
    

    In this example, the symbol exit is declared public in the main module so that it can be accessed from another source module (task).

    The main module also contains an external declaration of the symbol print. This declaration defines print to be a near label so that it can be accessed from themodule main, even though it is assumed to be located and declared public in another source module.

    A jmp instruction later in main has the label print as its destination.

    The symbol print is declared public in the task module so that it may be accessed from another module (main).

    The symbol exit is defined as a near label so that it can be accessed from this module, even though it is assumed to be located and declared public in the other
    module.

    Before this program can be executed, the two source files (one containing main, the other task) must be assembled individually, then linked together using a linker.

    The symbol listing for each source file shows the segment allocations.

    
    	MAIN.ASM  Symbol Table
    	Symbol Name                       Type   Value
    	??DATE                            Text   "21-05-89"
    	??FILENAME                        Text   "MAIN    "
    	??TIME                            Text   "14:20:27"
    	??VERSION                         Number 0100
    	@CODE                             Text   _TEXT
    	@CODESIZE                         Text   0
    	@CPU                              Text   0101H
    	@CURSEG                           Text   _TEXT
    	@DATA                             Text   DGROUP
    	@DATASIZE                         Text   0
    	@FILENAME                         Text   MAIN
    	@WORDSIZE                         Text   2
    	EXIT                              Near   _TEXT:0008
    	PRINT                             Near   ----:---- Extern
    	START                             Near   _TEXT:0000
    Groups & Segments                 Bit Size Align  Combine Class
    	DGROUP                            Group
    	  STACK                           16  0100 Para   Stack   STACK
    	  _DATA                           16  0000 Word   Public  DATA
    	_TEXT                             16  000D Word   Public  CODE
    
    	TASK.ASM  Symbol Table
    	Symbol Name                       Type   Value
    	??DATE                            Text   "21-05-89"
    	??FILENAME                        Text   "TASK    "
    	??TIME                            Text   "14:20:14"
    	??VERSION                         Number 0100
    	@CODE                             Text   _TEXT
    	@CODESIZE                         Text   0
    	@CPU                              Text   0101H
    	@CURSEG                           Text   _TEXT
    	@DATA                             Text   DGROUP
    	@DATASIZE                         Text   0
    	@FILENAME                         Text   TASK
    	@WORDSIZE                         Text   2
    	EXIT                              Near   ----:---- Extern
    	PRINT                             Near   _TEXT:0000
    	STRING                            Byte   DGROUP:0000
    Groups & Segments                 Bit Size Align  Combine Class
    	DGROUP                            Group
    	  _DATA                           16  0008 Word   Public  DATA
    	_TEXT                             16  000A Word   Public  CODE
    
    

    The map listing form the linker clearly shows how these segments have been combined.

    
    	MAIN.MAP (Output from Linker)
    	 Start  Stop   Length Name               Class
    	 00000H 00017H 00018H _TEXT              CODE
    	 00018H 0001FH 00008H _DATA              DATA
    	 00020H 0011FH 00100H STACK              STACK
    
    	Detailed map of segments
    	0000:0000 000D C=CODE S=_TEXT G=(none) M=MAIN.ASM ACBP=48
    	0000:000E 000A C=CODE S=_TEXT G=(none) M=TASK.ASM ACBP=48
    	0001:0008 0000 C=DATA S=_DATA G=DGROUP M=MAIN.ASM ACBP=48
    	0001:0008 0008 C=DATA S=_DATA G=DGROUP M=TASK.ASM ACBP=48
    	0002:0000 0100 C=STACK S=STACK G=DGROUP M=MAIN.ASM ACBP=74
    
    	  Address         Publics by Name
    	 0000:0008       EXIT
    	 0000:000E       PRINT
    
    	  Address         Publics by Value
    	 0000:0008       EXIT
    	 0000:000E       PRINT
    
    	Program entry point at 0000:0000
    
    

SEGMENT DIRECTIVES

So far, 8088 programs have been implemented using single segments with the directives


	 .CODE .STACK .DATA

This simplifies writing programs, but has several drawbacks.

  • little control over segment placing and combining
  • limited to three segments

The use of the segment directives provide the necessary controls for implementing large multiple segment programs. The programmer can specify which segments should be overlayed, combined, or stand alone.

Segment over-ride prefixs may be applied to certain instructions.


	 mov ax, cs:20h

obtains data from the code segment rather than the data segment.

The format for declaring a segment is,


	 name SEGMENT align combine_type class
	 name ENDS

Align specifies whether the segment starts at a byte, word or paragraph (10 byte) boundary. The default is paragraph.

Combine_type specifies whether the segment is PUBLIC, COMMON, MEMORY, PRIVATE, PUBLIC or STACK.


 PUBLIC The linker concatenates all segments with the same 
	name to form a single contigous segment. The length 
	is the sum of all the segments.

 COMMON The linker locates all segments with the same name 
	at the same address (overlayed on top of each 
	other). The length becomes the longest segment.

 MEMORY Same as Public

 PRIVATE The linker does not combine this segment with any 
	other segment.

 STACK The linker concatenates all segments with the same 
	name to form a single contiguous segment. The 
	length is the sum of all the segments. SS is 
	initialised to the beginning of the segment, SP to 
	the length of the segment.

Class controls the ordering of the segments at linking time. Segments with the same class name are loaded together. A segment of class CODE would be loaded before a segment of class STACK. The class name is enclosed using single or double quotes.

An example program follows.


	 TITLE Segdemo
	stck segment para private 'STACK'
	 db 200h dup (?)
	stck ends

	data segment byte public 'DATA'
		message db 'Hello there','$'
	data ends

	data2 segment byte public 'DATA2'
		message2 db 'Segment Data2','$'
	data2 ends

	code segment para private 'CODE'
	assume ds:data, ss:stck
	start: 	 mov ax, seg data
		 mov ds, ax
		 mov ah, 9
		 mov dx, offset message
		 int 21h

	 assume ds:data2
		 mov ax, seg data2
		 mov ds, ax
		 mov ah, 9
		 mov dx, offset message2
		 int 21h
		 mov ax, 4c00h
		 int 21h
	code ends
	end start

The map file for segdemo.exe is,


	 Start  Stop   Length Name               Class
	 00000H 001FFH 00200H STCK               STACK
	 00200H 0020BH 0000CH DATA               DATA
	 0020CH 00219H 0000EH DATA2              DATA2
	 00220H 0023CH 0001DH CODE               CODE

	Detailed map of segments
	0000:0000 0200 C=STACK S=STCK G=(none) M=SEGDEMO.ASM ACBP=60
	0020:0000 000C C=DATA S=DATA G=(none) M=SEGDEMO.ASM ACBP=28
	0020:000C 000E C=DATA2 S=DATA2 G=(none) M=SEGDEMO.ASM ACBP=28
	0022:0000 001D C=CODE S=CODE G=(none) M=SEGDEMO.ASM ACBP=60

This clearly shows the ordering (class) and concatenation of segments which are the same type.

 

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 )

Google+ photo

You are commenting using your Google+ 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 )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.