7 Assembly Program

 

In this lecture introduction to assembly programming will be discussed. The flow of operation for converting assembly code into machine code will also be discussed. We will also go through writing assembly programs for simple arithmetic processing.

 

1. Assembly programming

 

In this section we discuss Assembly language format and define some widely used terminology associated with Assembly language programming. While the CPU can work only in binary, it can do so at a very high speed. For humans, however, it is quite tedious and slow to deal with zeros and ones in order to program the computer. A program that consists of zeros and ones is called machine language.

 

In the early days of the computer, programmers coded programs in machine language. Although the hexadecimal system was used as a more efficient way to represent binary numbers, the process of working in machine code was still cumbersome for humans. Eventually, Assembly languages were developed that provided mnemonics for the machine code instructions, plus other features that made programming faster and less prone to error.

 

The term mnemonic is frequently used in computer science and engineering literature to refer to codes and abbreviations that are relatively easy to remember. Assembly language programs must be translated into machine code by a program called an assembler. Assembly language is referred to as a low-level language because it deals directly with the internal structure of the CPU. To program in Assembly language, the programmer must know all the registers of the CPU and the size of each, as well as other details. Hence the registers can be directly called and ports can be directly addressed.

 

Today, one can use many different programming languages, such as BASIC, Pascal, C, C++, Java, and numerous others. These languages are called high-level languages because the programmer does not have to be concerned with the internal details of the CPU. While an assembler is used to translate an Assembly language program into machine code (sometimes also called object code or opcode for operation code), high-level languages are translated into machine code by a program called a compiler. For instance, to write a program in C, one must use a C compiler to translate the program into machine language. Now we look at 8051 Assembly language format and use an 8051 assembler to create a ready-to-run program.

 

1.1 Structure of Assembly language

 

Assembly program consists of a series of lines of Assembly language instructions. Assembly language instruction consists of a mnemonic, optionally followed by one or two operands. Operands are the data items being manipulated, and the mnemonics are the commands to the CPU, telling it what to do with those items. Assembly language program is a series of statements, or lines, which are either Assembly language instructions such as MOV and SUB, or statements called directives. Instructions will tell the CPU what to do. The Directives will give directions to the assembler. Assembly language instruction consists of four fields

 

[label:] Mnemonic [operands] [;comment]

 

Mnemonic field is compulsory and all the other fields are optional. Figure. 1 shows the flow of operation that happens during conversion of assembly code into hexadecimal code. While writing an assembly program, an editor is used to type the program. The editor will produce an ascii file and save the file with extension ‘asm’ . The ‘asm’ file is fed into the assembler. Assembler will produce object(obj) file and list (lst)file. The program is then linked. The linker takes one or more object code files and produces an absolute object file with the extension “abs”. The ‘abs ’ file is fed into a program called “OH” (object to hex converter) and it creates a file with extension “hex”.

 

An example assembly code is given below.

   ORG 0H ;start(origin) at location

MOV R0, #08H ;load 08H into R0

MOV R1, #10H ;load 10H into R1

MOV A, #0 ;load 0 into A

ADD A, R0 ;add contents of R0 to A, A=A+R0
ADD A, R1 ;add contents of R1 to A, A= A+R1
HERE: SJMP HERE ;stay in this loop
END ;end of asm

 

This program does the job of adding 08H and 10H and stores it in the Accumulator. As per the instruction set of 8051, MOV and ADD are instructions to CPU, while ORG and END are directives to the assembler. ORG – indicates placing of program and END-indicates end of the source code. SJMP is the short jump and HERE is the label. An indefinite loop is created in this loop. Statements following a semicolon (;) – indicate comments. HERE – indicates a label in the program.

 

Different addressing modes for data transfer are shown below. These instructions are used in assembly codes for developing programs.

 

MOV A,#03H ; immediate addressing – data given directly

MOV A,R0     ; register addressing – data at register

MOV A,@RO ; indirect addressing – address given at register

MOVX A,@R0; indirect with external memory – data in external memory MOVC A, @A+DPTR ; indexed addressing

 

MOV is used to to move data to different register

 

MOV A,@R0 is used for moving the instruction from internal memory. MOVX A,@R0 is used for moving the instruction from external memory. The time taken for execution and the program speed will also depend on the addressing modes. For example, in the first addressing which is the immediate addressing mode, the data is moved directly to the accumulator, it takes very less time for the movement operation. In register addressing, the data movement will take one or two clock cycles. Indirect addressing takes more time since only the memory location of the data is given, the data is fetched by moving the pointer to the corresponding location. Similarly indirect with external memory will take more time and its processing speed is slow compared to the indirect addressing since the data have to be fetched from external memory. Some example instructions are listed below with different addressing formats

 

MOV A,#99H ; data 99 moved to A

MOV R0,A ; data at (A) moved to R0

MOV A,R1 ; data (R1) moved to A

MOV R2,R1 ; data (R1) moved to R2

MOV R3,A ; data (A) moved to R3

MOV R4,R3 ; data (R4) moved to (R3)

 

An example code for adding two numbers is given below, the results are stored in 20h.

 

MOV R1,#23H ; data 23h to R1

MOV A,#36H ; data 36h to A

ADD A, R1        ;A= (A)+(R1)

MOV 20H,A  ;(A) stored in address 20h

 

First the operand 23H is moved to the register R1 and the operand 36H is moved to the Accumulator. ADD instruction is used for doing the addition process of the two operands. Then, MOV instruction is used for moving the data from the accumulator to the address location 20H.

 

Another example code to subtract two numbers which are stored in registers R1 and R2 is given below and here the results are stored in R3.

 

CLR C ; clear carry

MOV A, R1 ; R1 to A

SUBB A, R2 ; R1-R2

MOV R3,A ; result to R3

Here: SJMP here ; terminate

 

Carry is always used in the subtraction operation. Hence, the carry should always be cleared before starting the process. Now the Carry will become zero. First the R1 register content is moved to accumulator hence A=R1. Then SUBB instruction is used for subtraction. Using this instruction, the process done is A=A-C-R1, which is nothing but A=R2-R1. Then the result is moved to the register R3 using MOV instruction. In this last statement (HERE: SJMP HERE) is used for making the system to rotate indefinitely at that place so that program appears like terminating.

 

Next example is for adding 3, 10 times and storing the result in location 35H.

 

MOV A,#00H ; clear accumulator

MOV R1,#0AH ; count 10

NEXT: ADD A,#03  ; A=A+03

DJNZ R1, NEXT; decrement R1 if not zero go to next

MOV 35H,A ; save result in 30H

HERE: SJMP HERE ; Terminate the program

END

 

In the above example, initially the accumulator value is set to zero. Then using the MOV instruction the register R1 is set to 10 which is the count value. Then the addition operation is done in which the accumulator content is now updated to 3 from 0. Next is the DJNZ instruction which decrements the Register R1 if it is not equal to zero. Now the Register R1 becomes R1=10 -1=9. Since R1 is not equal to zero the instruction is moved to the Loop NEXT. Again the content 3 is added to accumulator. Now the accumulator A becomes A=3+3=6. Likewise the loop NEXT is executed 10 times and the Accumulator value becomes 30. When the Register R1 becomes zero, loop is terminated and the Accumulator content is moved to the location 35H. In assembly, END is also used to show program is over. Before the end statement itself, the program terminates its operation.

 

The example program given below is used to find number of 1s in a given data:

 

MOV R1,08H ; count 8 bits

MOV R0,00H ; holds number of 1s

MOV A,#99H ; data to A

Next: RRC A ; rotate through carry

JNC zero ; no carry check next bit

INC R; since carry=1>r0=r0+1

zero:DJNZR1,Next ; decrement no. of bits

MOV 20H,R; store result in 20h

HERE:SJMP HERE ; terminate the program

END

Assume that the data contains 8 bits. Now the count 8 is stored in Register R1. Then the Register R0 is set to 0H. The data to be checked is 99H and it is stored in Accumulator. Now rotate the Accumulator right using the RRC Command. Assume that the 8 bit data is 01101101. Then initially the first bit 0 is set as carry bit. JNC instruction will check if that bit is equal to 1. If the bit is 1, then the register R0 is incremented by 1. Simultaneously the register R1 is decremented. Loop is executed. After the rotation operation, the last bit 1 will move to the first, now the carry bit is set to 1 and the loop operation continues. When the Register R1 becomes zero the loop is terminated. The number of 1s is stored in register R0 and it is moved to the location 20H.

 

The following is another example program to multiply two numbers and to store the results in internal memory.

 

MOV R0,#20H ; memory pointer

MOV A,@R0    ; from location 20h to A

MOV B,A             ; from A to B

INC RO               ; increment pointer

MOV A,@R0    ; from 21h to A

MUL AB                ; AxB

INC R0                  ; increment pointer

MOV @R0,A    ; LSB to 22h

INC R0                  ; increment pointer

MOV A,B              ; MSB to A

MOV @R0,A     ; mov to 23h

HERE: SJMP HERE ; terminate

 

operands from 20H and 21H are read and placed at A and B register. Multiplication done then results are placed at 22H and 23H. Similarly, the division program is given below and the results are stored in external memory.

 

MOV DPTR,#2000H ; memory pointer to dptr

MOVX A,@DPTR      ; memory to A

MOV B,A                         ; A to B

INC DPTR                       ; increment pointer

MOVX A,@DPTR       ; 2001h to A

DIV AB                               ; A/B

INC DPTR                      ; increment pointer

MOVX @DPTR,A       ; quotient to 2002h

MOV A,B                          ; remainder from B to A

INC DPTR                        ; increment pointer

MOVX @DPTR,A        ; store remainder in 2003h

HERE:SJMP HERE   ; terminate

 

operands from external memory (2000H and 2001H) are read and placed at A and B register. Division executed, quotient and remainder placed at (2002H and 2003H) external memory

 

A general example for finding the factorial of a given number is always done with high level language. So in assembly also, we will go through it. As we know (n! =1 x 2 x 3 x….x n) The following program does this job.

 

MOV A,#n    ; n to a

MOV B,A        ; A to B

DEC A              ; decrement A

NEXT:

MUL AB           ;nxn-1xn-2x….

DEC A              ; A=A-1

CJNE A,#01H,NEXT ; if A not equal to 1 goto next

MOV 20H,A                     ; save LSB in 20h

MOV 21H,B                     ; save LSB in 21h

HERE: SJMP HERE  ; terminate

 

multiplication of 1 x 2 x 3 x ..n done and results stored at memory locations 20H, 21H

 

3. Summary

 

In this lecture, first an introduction to assembly programming is given.

Then procedure for converting assembly code into machine code is also discussed. Assembly programs for simple arithmetic processing is given and the program flow is discussed.

 

4. References

  1. The 8051 Microcontroller and Embedded Systems Using Assembly and C Second Edition Muhammad Ali Mazidi, Janice Gillispie Mazidi and Rolin D. McKinlay.
  2. http://what-when-how.com/8051-microcontroller
  3. Instruction set for 8051