Search This Blog

Friday, April 13, 2012

Macros and Nested Macros

Macro can be defined as a group of repetitive instructions in a program that are codified only once but can be repeated n number of times.

Syntax
Macro_name MACRO argument1, argument2,…..argumentn
                Statement 1
                Statement 2
                Statement k
EndM

An actual argument can be any variable, immediate value or a register name.  They may also be duplicates of other names like labels, variables etc.

A macro call designed to generate assembly language instructions must be called in a code segment.
A macro call designed to generate data definitions must appear in a portion o f a program where it will not be considered as an instruction.

Lets take an example. A complex 8086 program contains many complicated procedures. Each time a procedure is called all the flags need to be stored in stack and then retrieved. Adding long pushing lines at the beginning of the procedures and poping lines at the end of the procedure. So instead of writing these lines repetitively in every procedure we create 2 macros. One for pushing and other for poping. Like this.
PUSH_ALL MACRO
}  PUSH F
}  PUSH AX
}  PUSH BX
}  PUSH CX
}  PUSH DX
}  PUSH BP
}  PUSH SI
}  PUSH DI
}  PUSH DS
}  PUSH ES
}  PUSH SS
ENDM

Similar to this one there will be POP_ALL MACRO.

Now calling macros inside a procedure.
RATE PROC FAR
ASSUME CS:PROCEDURES, DS:PARAMETERS
PUSH_ALL ; macro call
;initialize statements
MOV AX, PARAMETERS
MOV DS, AX
RATE ENDP
PROCEDURES ENDS

A macro definition can occur anywhere before END directive.
A macro definition cannot occur inside another macro. Usually all macros are placed at beginning of program before segment definition.
A macro definition is not assembled until macro is called. Each macro call is replaced by statements in the macro.

Passing parameters to a macro.
Simple example
MOV_NUMBERS MACRO NUMBER,SOURCE,DESTINATION
MOV CX,NUMBER
LEA SI, SOURCE
LEA DI, DESTINATION
CLD
REP MOVSB; copy from SI to DI till counter 0
MOV_NUMBERS ENDM


Nested macros.

A macro calling another macro is called a nested macro. TASM and MASM can contain a macro that calls a previously defined macros. All macros should be defined before segment definition though their order can be anything. Like for example…
DISPLAY_CHAR  MACRO  CHAR
                           PUSH  AX
                           PUSH  DX
                           MOV  AH , 02H
                           MOV  DL ,  CHAR
                           INT  21H
                           POP  DX
                           POP  AX
ENDM
CRLF  MACRO
                      DIPLAY_CHAR  0DH
                      DISPLAY_CHAR  0AH
ENDM

Monday, March 19, 2012

Assembler Directives of 8086/8088

ASSUME
This directive tells the assembler the name of the logical segment it should use for a specified segment. For example ASSUME CS:CODE, tells the assembler that the instructions for a program are in a logical segment named CODE. The 8086 works directly with only 4 physical segments: a Code segment, a data segment, a stack segment, and an extra segment.
DB – Define Byte
This directive is used to declare a byte type variable or to store a byte in memory location. For example

NAME DB ‘THOMAS’;
VALUES DB ‘0’,’1’,’2’,’3’;
DD – Define Doubleword
This directive is used to define a variable of type doubleword or to reserve storage location of type doubleword in memory. For example

POINTER DD 12341234H
DQ – Define Quadword
This directive is used to define a variable of type quadword or to reserve storage location of type quadword in memory. For example

POINTER DQ  1234123412341234H
DT – Define Ten Bytes
This directive is used to define a variable which is 10 bytes in length or to reserve 10 bytes of storage in the memory. For example

POINTER DT 11223344556677889900
DW – Define Word
This directive is used to define a variable of type word or to reserve storage location of type word in memory. For example

ARRAY DW 100DUP(0) ; defines an array of size 100 all initialized to 0.
MULTIPLIER DW 1234h; defines a variable multiplier of value 1234h
ENDS
This directive is used with name of the segment to indicate the end of that logic segment. For example

CODE SEGMENT ; this statement starts the segment

CODE ENDS ; this statement ends the segment
EQU
This directive is used to give a name to some value or to a symbol. Each time the assembler finds the name in the program, it will replace the name with the value or symbol you given to that name. for example

FACTOR EQU 03H ; this equates factor to 03h can be used as
ADD AL, FACTOR ; When it codes this instruction the assembler will code it as ADDAL, 03H ;The advantage of using EQU in this manner is, if FACTOR is used many no of times in a program and you want to change the value, all you had to do is change the EQU statement at beginning, it will changes the rest of all.
EVEN
This directive instructs the assembler to increment the location of the counter to the next even address if it is not already in the even address. If the word is at even address 8086 can read a memory in 1 bus cycle.

If the word starts at an odd address, the 8086 will take 2 bus cycles to get the data. A series of words can be read much more quickly if they are at even address. When EVEN is used the location counter will simply incremented to next address and NOP instruction is inserted in that incremented location. For example

DATA1 SEGMENT
; Location counter will point to 0009 after assembler reads next statement
SALES DB 9 DUP(?) ;declare an array of 9 bytes
EVEN ; increment location counter to 000AH
RECORD DW 100 DUP(0) ;Array of 100 words will start from an even address for quicker read
DATA1 ENDS
GROUP
This directive is used to group the logical segments named after the directive into one logical group segment.
INCLUDE
This directive is used to insert a block of source code from the named file into the current source module.
Rest will be added with time……

Various addressing modes of 8086/8088

1)      Register Addressing mode
2)      Immediate Addressing mode
3)      Register Indirect Addressing mode
4)      Direct Addressing mode
5)      Indexed Addressing mode
6)      Base Relative Addressing mode
7)      Base Indexed Addressing mode

Register Addressing Mode
Data transfer using registers is called register addressing mode. Here operand value is present in register. For example

MOV AL,BL;
MOV AX,BX;
Immediate Addressing mode
When data is stored in code segment instead of data segment immediate addressing mode is used. Here operand value is present in the instruction. For example

MOV AX, 12345;
Direct Addressing mode
When direct memory address is supplied as part of the instruction is called direct addressing mode. Operand offset value with respect to data segment is given in instruction. For example

MOV AX, [1234];
ADD AX, [1234];
Register Indirect Addressing mode
Here operand offset is given in a cpu register. Register used are BX, SI(source index), DI(destination index),  or BP(base pointer). BP holds offset w.r.t Stack segment, but SI,DI and BX refer to data segment. For example

MOV [BX],AX;
ADD AX, [SI];
Indexed Addressing mode
Here operand offset is given by a sum of a value held in either SI, or DI register and a constant displacement specified as an operand. For example
Lets take arrays as an example. This is very efficient way of accessing arrays.
My_array  DB ‘1’, ‘2’, ‘3’,’4,’5’;

MOV SI, 3;
MOV AL, My_array[3];

So AL holds value 4.
Base Relative Addressing mode
Operand offset given by a sum of a value held either in BP, or BX and a constant offset sepecified as an operand. For example

MOV AX,[BP+1];
JMP [BX+1];
Base Indexed
Here operand offset is given by sum of either BX or BP with either SI or DI. For example

MOV AX, [BX+SI]
 JMP [BP+DI]