{"id":73,"date":"2018-07-26T09:41:30","date_gmt":"2018-07-26T09:41:30","guid":{"rendered":"http:\/\/csp13.epgpbooks.inflibnet.ac.in\/?post_type=chapter&#038;p=73"},"modified":"2018-08-10T11:09:11","modified_gmt":"2018-08-10T11:09:11","slug":"assembly-program","status":"publish","type":"chapter","link":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/chapter\/assembly-program\/","title":{"rendered":"Assembly Program"},"content":{"raw":"<div>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">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.<\/p>\r\n&nbsp;\r\n\r\n<strong>1. Assembly programming<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">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<em>.<\/em><\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">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.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">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<em>.<\/em> 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.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">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 <em>object code<\/em> or opcode for operation code), high-level languages are translated into machine code by a program called a compiler<em>.<\/em> 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.<\/p>\r\n\r\n<\/div>\r\n<div>\r\n\r\n&nbsp;\r\n\r\n<strong>1.1 Structure of Assembly language<\/strong>\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">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<\/p>\r\n&nbsp;\r\n\r\n[label:] Mnemonic [operands] [;comment]\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">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 \u2018asm\u2019 . The \u2018asm\u2019 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 \u201cabs\u201d. The \u2018abs \u2019 file is fed into a program called \u201cOH\u201d (object to hex converter) and it creates a file with extension \u201chex\u201d.<\/p>\r\n&nbsp;\r\n\r\n<img class=\"size-full wp-image-76 aligncenter\" src=\"http:\/\/csp13.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/62\/2018\/07\/2-30.png\" alt=\"\" width=\"454\" height=\"309\" \/>\r\n\r\nAn example assembly code is given below.\r\n\r\n<\/div>\r\n<div>\r\n\r\n\u00a0 \u00a0ORG 0H\u00a0;start(origin) at location\r\n\r\nMOV R0, #08H\u00a0;load 08H into R0\r\n\r\nMOV R1, #10H\u00a0;load 10H into R1\r\n\r\nMOV A, #0\u00a0;load 0 into A\r\n\r\n<\/div>\r\n<div>\r\n<table class=\"aligncenter\" style=\"width: 60%\" border=\"1\">\r\n<tbody>\r\n<tr>\r\n<td>ADD A, R0<\/td>\r\n<td>;add contents of R0 to A, A=A+R0<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>ADD A, R1<\/td>\r\n<td>;add contents of R1 to A, A= A+R1<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>HERE: SJMP HERE ;stay in this loop<\/td>\r\n<\/tr>\r\n<tr>\r\n<td>END<\/td>\r\n<td>;end of asm<\/td>\r\n<\/tr>\r\n<\/tbody>\r\n<\/table>\r\n&nbsp;\r\n<p style=\"text-align: justify\">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 \u2013 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 \u2013 indicates a label in the program.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">Different addressing modes for data transfer are shown below. These instructions are used in assembly codes for developing programs.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">MOV A,#03H ; immediate addressing - data given directly<\/p>\r\n<p style=\"text-align: justify\">MOV A,R0\u00a0\u00a0\u00a0\u00a0 ; register addressing - data at register<\/p>\r\n<p style=\"text-align: justify\">MOV A,@RO ; indirect addressing - address given at register<\/p>\r\n<p style=\"text-align: justify\">MOVX A,@R0; indirect with external memory - data in external memory MOVC A, @A+DPTR ; indexed addressing<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">MOV is used to to move data to different register<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">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<\/p>\r\n&nbsp;\r\n\r\nMOV A,#99H ; data 99 moved to A\r\n\r\nMOV R0,A ; data at (A) moved to R0\r\n\r\nMOV A,R1 ; data (R1) moved to A\r\n\r\nMOV R2,R1 ; data (R1) moved to R2\r\n\r\nMOV R3,A ; data (A) moved to R3\r\n\r\nMOV R4,R3 ; data (R4) moved to (R3)\r\n\r\n&nbsp;\r\n\r\nAn example code for adding two numbers is given below, the results are stored in 20h.\r\n\r\n&nbsp;\r\n\r\nMOV R1,#23H ; data 23h to R1\r\n\r\nMOV A,#36H ; data 36h to A\r\n\r\nADD A, R1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ;A= (A)+(R1)\r\n\r\nMOV 20H,A\u00a0 ;(A) stored in address 20h\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\"><span style=\"font-size: 1em;text-align: justify\">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.<\/span><\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><span style=\"font-size: 1em\">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.<\/span><\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">CLR C\u00a0; clear carry<\/span><\/p>\r\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">MOV A, R1\u00a0; R1 to A<\/span><\/p>\r\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">SUBB A, R2\u00a0; R1-R2<\/span><\/p>\r\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">MOV R3,A\u00a0; result to R3<\/span><\/p>\r\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">Here: SJMP here\u00a0<\/span><span style=\"text-align: initial;font-size: 1em\">; terminate<\/span><\/p>\r\n\r\n<\/div>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">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.<\/span><\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">Next example is for adding 3, 10 times and storing the result in location 35H.<\/span><\/p>\r\n\r\n<div>\r\n\r\n&nbsp;\r\n\r\nMOV A,#00H ; clear accumulator\r\n\r\nMOV R1,#0AH ; count 10\r\n\r\nNEXT: ADD A,#03\u00a0 ; A=A+03\r\n\r\nDJNZ R1, NEXT; decrement R1 if not zero go to next\r\n\r\nMOV 35H,A ; save result in 30H\r\n\r\nHERE: SJMP HERE ; Terminate the program\r\n\r\nEND\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">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.<\/p>\r\n&nbsp;\r\n\r\nThe example program given below is used to find number of 1s in a given data:\r\n\r\n&nbsp;\r\n\r\nMOV R1,08H ; count 8 bits\r\n\r\nMOV R0,00H ; holds number of 1s\r\n\r\nMOV A,#99H ; data to A\r\n\r\n<span style=\"font-size: 1em\">Next: <\/span><span style=\"font-size: 1em\">RRC A ; rotate through carry<\/span>\r\n\r\n<span style=\"font-size: 1em\">JNC zero ; no carry check next bit<\/span>\r\n\r\n<span style=\"font-size: 1em\">INC R<\/span><span style=\"font-size: 1em\">0\u00a0<\/span><span style=\"font-size: 1em\">; since carry=1<\/span><span style=\"font-size: 1em\">-<\/span><span style=\"font-size: 1em\">&gt;r0=r0+1<\/span>\r\n\r\n<span style=\"font-size: 1em\">zero:<\/span><span style=\"font-size: 1em\">DJNZ<\/span><span style=\"font-size: 1em\">R1,Next ; decrement no. of bits<\/span>\r\n\r\n<span style=\"font-size: 1em\">MOV 20H,R<\/span><span style=\"font-size: 1em\">0\u00a0<\/span><span style=\"font-size: 1em\">; store result in 20h<\/span>\r\n\r\n<span style=\"font-size: 1em\">HERE:SJMP HERE ; terminate the program<\/span>\r\n\r\n<\/div>\r\n<div>\r\n\r\nEND\r\n<p style=\"text-align: justify\">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.<\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\">The following is another example program to multiply two numbers and to store the results in internal memory.<\/p>\r\n&nbsp;\r\n\r\nMOV R0,#20H ; memory pointer\r\n\r\nMOV A,@R0\u00a0\u00a0\u00a0 ; from location 20h to A\r\n\r\nMOV B,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; from A to B\r\n\r\nINC RO\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer\r\n\r\nMOV A,@R0\u00a0\u00a0\u00a0 ; from 21h to A\r\n\r\nMUL AB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; AxB\r\n\r\nINC R0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer\r\n\r\nMOV @R0,A\u00a0\u00a0\u00a0 ; LSB to 22h\r\n\r\nINC R0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer\r\n\r\nMOV A,B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; MSB to A\r\n\r\nMOV @R0,A\u00a0\u00a0\u00a0\u00a0 ; mov to 23h\r\n\r\nHERE: SJMP HERE ; terminate\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\">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.<\/p>\r\n&nbsp;\r\n\r\nMOV DPTR,#2000H ; memory pointer to dptr\r\n\r\nMOVX A,@DPTR\u00a0\u00a0\u00a0\u00a0\u00a0 ; memory to A\r\n\r\nMOV B,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A to B\r\n\r\nINC DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer\r\n\r\nMOVX A,@DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; 2001h to A\r\n\r\nDIV AB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A\/B\r\n\r\nINC DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer\r\n\r\nMOVX @DPTR,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; quotient to 2002h\r\n\r\nMOV A,B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; remainder from B to A\r\n\r\nINC DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer\r\n\r\nMOVX @DPTR,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; store remainder in 2003h\r\n\r\nHERE:SJMP HERE\u00a0\u00a0 ; terminate\r\n\r\n&nbsp;\r\n<p style=\"text-align: justify\"><span style=\"text-align: justify;font-size: 1em\">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<\/span><\/p>\r\n&nbsp;\r\n<p style=\"text-align: justify\"><span style=\"font-size: 1em\">A general example for <\/span><strong style=\"font-size: 1em\">finding the factorial<\/strong><span style=\"font-size: 1em\"> 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<\/span><span style=\"text-align: initial;font-size: 1em\">....x n) The following program does this job.<\/span><\/p>\r\n\r\n<\/div>\r\n&nbsp;\r\n\r\nMOV A,#n\u00a0\u00a0\u00a0 ; n to a\r\n\r\nMOV B,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A to B\r\n\r\nDEC A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; decrement A\r\n\r\nNEXT:\r\n\r\nMUL AB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ;nxn-1xn-2x\u2026.\r\n\r\nDEC A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A=A-1\r\n\r\nCJNE A,#01H,NEXT ; if A not equal to 1 goto next\r\n\r\nMOV 20H,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; save LSB in 20h\r\n\r\nMOV 21H,B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; save LSB in 21h\r\n\r\nHERE: SJMP HERE\u00a0 ; terminate\r\n\r\n&nbsp;\r\n\r\nmultiplication of 1 x 2 x 3 x ..n done and results stored at memory locations 20H, 21H\r\n\r\n&nbsp;\r\n\r\n<strong>3. Summary<\/strong>\r\n\r\n&nbsp;\r\n\r\nIn this lecture, first an introduction to assembly programming is given.\r\n<p style=\"text-align: justify\">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.<\/p>\r\n&nbsp;\r\n\r\n<strong>4. References<\/strong>\r\n<ol>\r\n \t<li>The 8051 Microcontroller and Embedded Systems Using Assembly and C Second Edition Muhammad Ali Mazidi, Janice Gillispie Mazidi and Rolin D. McKinlay.<\/li>\r\n \t<li>http:\/\/what-when-how.com\/8051-microcontroller<\/li>\r\n \t<li>Instruction set for 8051<\/li>\r\n<\/ol>","rendered":"<div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>1. Assembly programming<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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<em>.<\/em><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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<em>.<\/em> 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.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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 <em>object code<\/em> or opcode for operation code), high-level languages are translated into machine code by a program called a compiler<em>.<\/em> 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.<\/p>\n<\/div>\n<div>\n<p>&nbsp;<\/p>\n<p><strong>1.1 Structure of Assembly language<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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<\/p>\n<p>&nbsp;<\/p>\n<p>[label:] Mnemonic [operands] [;comment]<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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 \u2018asm\u2019 . The \u2018asm\u2019 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 \u201cabs\u201d. The \u2018abs \u2019 file is fed into a program called \u201cOH\u201d (object to hex converter) and it creates a file with extension \u201chex\u201d.<\/p>\n<p>&nbsp;<\/p>\n<p><img loading=\"lazy\" decoding=\"async\" class=\"size-full wp-image-76 aligncenter\" src=\"http:\/\/csp13.epgpbooks.inflibnet.ac.in\/wp-content\/uploads\/sites\/62\/2018\/07\/2-30.png\" alt=\"\" width=\"454\" height=\"309\" srcset=\"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-content\/uploads\/sites\/62\/2018\/07\/2-30.png 454w, https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-content\/uploads\/sites\/62\/2018\/07\/2-30-300x204.png 300w, https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-content\/uploads\/sites\/62\/2018\/07\/2-30-65x44.png 65w, https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-content\/uploads\/sites\/62\/2018\/07\/2-30-225x153.png 225w, https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-content\/uploads\/sites\/62\/2018\/07\/2-30-350x238.png 350w\" sizes=\"auto, (max-width: 454px) 100vw, 454px\" \/><\/p>\n<p>An example assembly code is given below.<\/p>\n<\/div>\n<div>\n<p>\u00a0 \u00a0ORG 0H\u00a0;start(origin) at location<\/p>\n<p>MOV R0, #08H\u00a0;load 08H into R0<\/p>\n<p>MOV R1, #10H\u00a0;load 10H into R1<\/p>\n<p>MOV A, #0\u00a0;load 0 into A<\/p>\n<\/div>\n<div>\n<table class=\"aligncenter\" style=\"width: 60%\">\n<tbody>\n<tr>\n<td>ADD A, R0<\/td>\n<td>;add contents of R0 to A, A=A+R0<\/td>\n<\/tr>\n<tr>\n<td>ADD A, R1<\/td>\n<td>;add contents of R1 to A, A= A+R1<\/td>\n<\/tr>\n<tr>\n<td>HERE: SJMP HERE ;stay in this loop<\/td>\n<\/tr>\n<tr>\n<td>END<\/td>\n<td>;end of asm<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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 \u2013 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 (;) &#8211; indicate comments. HERE \u2013 indicates a label in the program.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">Different addressing modes for data transfer are shown below. These instructions are used in assembly codes for developing programs.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">MOV A,#03H ; immediate addressing &#8211; data given directly<\/p>\n<p style=\"text-align: justify\">MOV A,R0\u00a0\u00a0\u00a0\u00a0 ; register addressing &#8211; data at register<\/p>\n<p style=\"text-align: justify\">MOV A,@RO ; indirect addressing &#8211; address given at register<\/p>\n<p style=\"text-align: justify\">MOVX A,@R0; indirect with external memory &#8211; data in external memory MOVC A, @A+DPTR ; indexed addressing<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">MOV is used to to move data to different register<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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<\/p>\n<p>&nbsp;<\/p>\n<p>MOV A,#99H ; data 99 moved to A<\/p>\n<p>MOV R0,A ; data at (A) moved to R0<\/p>\n<p>MOV A,R1 ; data (R1) moved to A<\/p>\n<p>MOV R2,R1 ; data (R1) moved to R2<\/p>\n<p>MOV R3,A ; data (A) moved to R3<\/p>\n<p>MOV R4,R3 ; data (R4) moved to (R3)<\/p>\n<p>&nbsp;<\/p>\n<p>An example code for adding two numbers is given below, the results are stored in 20h.<\/p>\n<p>&nbsp;<\/p>\n<p>MOV R1,#23H ; data 23h to R1<\/p>\n<p>MOV A,#36H ; data 36h to A<\/p>\n<p>ADD A, R1\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ;A= (A)+(R1)<\/p>\n<p>MOV 20H,A\u00a0 ;(A) stored in address 20h<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><span style=\"font-size: 1em;text-align: justify\">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.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><span style=\"font-size: 1em\">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.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">CLR C\u00a0; clear carry<\/span><\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">MOV A, R1\u00a0; R1 to A<\/span><\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">SUBB A, R2\u00a0; R1-R2<\/span><\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">MOV R3,A\u00a0; result to R3<\/span><\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">Here: SJMP here\u00a0<\/span><span style=\"text-align: initial;font-size: 1em\">; terminate<\/span><\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">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.<\/span><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: initial;font-size: 1em\">Next example is for adding 3, 10 times and storing the result in location 35H.<\/span><\/p>\n<div>\n<p>&nbsp;<\/p>\n<p>MOV A,#00H ; clear accumulator<\/p>\n<p>MOV R1,#0AH ; count 10<\/p>\n<p>NEXT: ADD A,#03\u00a0 ; A=A+03<\/p>\n<p>DJNZ R1, NEXT; decrement R1 if not zero go to next<\/p>\n<p>MOV 35H,A ; save result in 30H<\/p>\n<p>HERE: SJMP HERE ; Terminate the program<\/p>\n<p>END<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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.<\/p>\n<p>&nbsp;<\/p>\n<p>The example program given below is used to find number of 1s in a given data:<\/p>\n<p>&nbsp;<\/p>\n<p>MOV R1,08H ; count 8 bits<\/p>\n<p>MOV R0,00H ; holds number of 1s<\/p>\n<p>MOV A,#99H ; data to A<\/p>\n<p><span style=\"font-size: 1em\">Next: <\/span><span style=\"font-size: 1em\">RRC A ; rotate through carry<\/span><\/p>\n<p><span style=\"font-size: 1em\">JNC zero ; no carry check next bit<\/span><\/p>\n<p><span style=\"font-size: 1em\">INC R<\/span><span style=\"font-size: 1em\">0\u00a0<\/span><span style=\"font-size: 1em\">; since carry=1<\/span><span style=\"font-size: 1em\">&#8211;<\/span><span style=\"font-size: 1em\">&gt;r0=r0+1<\/span><\/p>\n<p><span style=\"font-size: 1em\">zero:<\/span><span style=\"font-size: 1em\">DJNZ<\/span><span style=\"font-size: 1em\">R1,Next ; decrement no. of bits<\/span><\/p>\n<p><span style=\"font-size: 1em\">MOV 20H,R<\/span><span style=\"font-size: 1em\">0\u00a0<\/span><span style=\"font-size: 1em\">; store result in 20h<\/span><\/p>\n<p><span style=\"font-size: 1em\">HERE:SJMP HERE ; terminate the program<\/span><\/p>\n<\/div>\n<div>\n<p>END<\/p>\n<p style=\"text-align: justify\">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.<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">The following is another example program to multiply two numbers and to store the results in internal memory.<\/p>\n<p>&nbsp;<\/p>\n<p>MOV R0,#20H ; memory pointer<\/p>\n<p>MOV A,@R0\u00a0\u00a0\u00a0 ; from location 20h to A<\/p>\n<p>MOV B,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; from A to B<\/p>\n<p>INC RO\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer<\/p>\n<p>MOV A,@R0\u00a0\u00a0\u00a0 ; from 21h to A<\/p>\n<p>MUL AB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; AxB<\/p>\n<p>INC R0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer<\/p>\n<p>MOV @R0,A\u00a0\u00a0\u00a0 ; LSB to 22h<\/p>\n<p>INC R0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer<\/p>\n<p>MOV A,B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; MSB to A<\/p>\n<p>MOV @R0,A\u00a0\u00a0\u00a0\u00a0 ; mov to 23h<\/p>\n<p>HERE: SJMP HERE ; terminate<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\">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.<\/p>\n<p>&nbsp;<\/p>\n<p>MOV DPTR,#2000H ; memory pointer to dptr<\/p>\n<p>MOVX A,@DPTR\u00a0\u00a0\u00a0\u00a0\u00a0 ; memory to A<\/p>\n<p>MOV B,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A to B<\/p>\n<p>INC DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer<\/p>\n<p>MOVX A,@DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; 2001h to A<\/p>\n<p>DIV AB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A\/B<\/p>\n<p>INC DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer<\/p>\n<p>MOVX @DPTR,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; quotient to 2002h<\/p>\n<p>MOV A,B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; remainder from B to A<\/p>\n<p>INC DPTR\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; increment pointer<\/p>\n<p>MOVX @DPTR,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; store remainder in 2003h<\/p>\n<p>HERE:SJMP HERE\u00a0\u00a0 ; terminate<\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><span style=\"text-align: justify;font-size: 1em\">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<\/span><\/p>\n<p>&nbsp;<\/p>\n<p style=\"text-align: justify\"><span style=\"font-size: 1em\">A general example for <\/span><strong style=\"font-size: 1em\">finding the factorial<\/strong><span style=\"font-size: 1em\"> 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<\/span><span style=\"text-align: initial;font-size: 1em\">&#8230;.x n) The following program does this job.<\/span><\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<p>MOV A,#n\u00a0\u00a0\u00a0 ; n to a<\/p>\n<p>MOV B,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A to B<\/p>\n<p>DEC A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; decrement A<\/p>\n<p>NEXT:<\/p>\n<p>MUL AB\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ;nxn-1xn-2x\u2026.<\/p>\n<p>DEC A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; A=A-1<\/p>\n<p>CJNE A,#01H,NEXT ; if A not equal to 1 goto next<\/p>\n<p>MOV 20H,A\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; save LSB in 20h<\/p>\n<p>MOV 21H,B\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 ; save LSB in 21h<\/p>\n<p>HERE: SJMP HERE\u00a0 ; terminate<\/p>\n<p>&nbsp;<\/p>\n<p>multiplication of 1 x 2 x 3 x ..n done and results stored at memory locations 20H, 21H<\/p>\n<p>&nbsp;<\/p>\n<p><strong>3. Summary<\/strong><\/p>\n<p>&nbsp;<\/p>\n<p>In this lecture, first an introduction to assembly programming is given.<\/p>\n<p style=\"text-align: justify\">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.<\/p>\n<p>&nbsp;<\/p>\n<p><strong>4. References<\/strong><\/p>\n<ol>\n<li>The 8051 Microcontroller and Embedded Systems Using Assembly and C Second Edition Muhammad Ali Mazidi, Janice Gillispie Mazidi and Rolin D. McKinlay.<\/li>\n<li>http:\/\/what-when-how.com\/8051-microcontroller<\/li>\n<li>Instruction set for 8051<\/li>\n<\/ol>\n","protected":false},"author":2,"menu_order":7,"template":"","meta":{"pb_show_title":"on","pb_short_title":"","pb_subtitle":"","pb_authors":[],"pb_section_license":""},"chapter-type":[],"contributor":[],"license":[],"class_list":["post-73","chapter","type-chapter","status-publish","hentry"],"part":3,"_links":{"self":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/pressbooks\/v2\/chapters\/73","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/pressbooks\/v2\/chapters"}],"about":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/wp\/v2\/types\/chapter"}],"author":[{"embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/wp\/v2\/users\/2"}],"version-history":[{"count":6,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/pressbooks\/v2\/chapters\/73\/revisions"}],"predecessor-version":[{"id":440,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/pressbooks\/v2\/chapters\/73\/revisions\/440"}],"part":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/pressbooks\/v2\/parts\/3"}],"metadata":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/pressbooks\/v2\/chapters\/73\/metadata\/"}],"wp:attachment":[{"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/wp\/v2\/media?parent=73"}],"wp:term":[{"taxonomy":"chapter-type","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/pressbooks\/v2\/chapter-type?post=73"},{"taxonomy":"contributor","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/wp\/v2\/contributor?post=73"},{"taxonomy":"license","embeddable":true,"href":"https:\/\/ebooks.inflibnet.ac.in\/csp13\/wp-json\/wp\/v2\/license?post=73"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}