Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Cs 223 / Cmpe 221: Computer Organization and Assembly Language Lab – 2 Part - I Objective The objective of this part is to understand and make use of a special register called the FLAGS register in the IA-32 architecture. This register contains a group of status flags and control flags. For this lab we are mainly interested in status flags that are affected by performing arithmetic operations through ADD and SUB directives. We have many general-purpose registers available in the IA-32 architecture. Each register can be referred through different variations of the same name to signify different number of bits. Example Lets say the register EAX has the following HEX value 1234ABCD EAX = 1234ABCDh AX = ABCDh AH = ABh AL = CDh We will now move on to explore the details of the flags register. 1 Detail of the FLAGS register (Source: IA-32 Intel® Architecture, Software Developer’s Manual) For this lab, we are only interested in bit numbers 0, 6, 7 and 11. Each bit is illustrated with an example below. Bit 6, Zero Flag (ZF) ;--------SAMPLE 1-------mov cx, 1 sub cx, 1 ;cx=0, ZF=1 Bit 7, Sign Flag (SF) ;--------SAMPLE 2-------mov bx, 0 sub bx, 1 ; cx=-1, SF=1 add bx, 2 ; cx=1, SF=0 Bit 0, Carry Flag (CF) For unsigned arithmetic. Used to detect overflow in unsigned arithmetic. ;--------SAMPLE 3-------mov al, 0FFh add al, 1 ; al=0, CF=1 ;--------SAMPLE 4------mov ax, 00FFh add ax, 1 ; ax=0100h, CF=0 Bit 11, Overflow (OF) For signed arithmetic ;--------SAMPLE 5------mov al, 127 ; i.e. +124 add al, 1 ; OF=1 ;--------SAMPLE 6------mov al, -128 sub a1, 1 ; OF=1 2 Before writing the sample code above, please once again consider the skeleton of a simple assembly language program Quick Recap – Skeleton of a simple assembly Language program TITLE a simple assembly ; program dosseg .MODEL small .STACK 4096 .data ; variables .code main PROC mov ax, @data mov ds, ax ; your program mov ax, 4c00h int 21h main ENDP END main Methods for reading flag register There are two ways to read the FLAGS register from the debugger. First, after launching the debugger, observe the ‘FL’ register, which is a 16-bit register. The debugger will show you hex values. Thus you would first need to convert it into a binary number and then figure out which flag is set and which is not. Method 1 Example for Method 1 From the window on your left FL=3282 15 14 13 12 11 10 9 Method 2 8 7 6 5 4 3 2 1 0 0 0 1 1 0 0 1 0 1 0 0 0 0 0 1 0 We can now deduce the following values: Bit 1 Name Carry Flag Symbol Value CF 0 6 7 Zero Flag Sign Flag ZF SF 0 1 11 Overflow Flag OF 0 3 The second method involves directly reading the status of the flags from the group of 8 abbreviations at the bottom of the register window as shown above. You can use the following table to figure the status of each flag. Confirm that the status of the flags read from both methods is identical. For use with Method 2 OverDirecflow tion On OV DN Off NV UP Sign EI DI Interrupt NG PL Zero ZR NZ Auxiliary Parity Carry AC PE NA PO Carry CY NC Exercise 1 Using the code samples presented earlier, fill out the following table indicating the values of the concerned flags (using the debugger) on completion of the sample code. Sample No. Value of FL Binary Value of FL CF (bit 1) ZF (bit 6) SF (bit 7) OF (bit 11) Sample 1 Sample 2 Sample 3 Sample 4 Sample 5 Sample 6 4 Part II : Here we are going to go through two things 1. Learning how to use arrays through indirect addressing 2. Learning how to use loops in Assembly Language Armed with this knowledge you will then go through two simple programming exercises As always, we are assuming that you have already read the assigned chapter, i.e. chapter 4. How to use arrays in your program Indirect Addressing: The concept of indirect addressing is very important when working with arrays in assembly language. It allows you to use registers as pointers to memory locations in you programs. You can indirectly access a memory location through a register containing an address by putting square brackets ([]) around the name of the register. Consider for Example mov ax, bx ; ax = bx – copies the contents of bx into ax, while mov ax, [bx] ; loads ax with the value stored at the memory location who’s address is in bx The use of arrays is illustrated with the following example and the associated explanation. It is implied that you have to add the proper skeleton (template) of an assembly language program to successfully compile it. Example for Arrays The subsequent code declares an array of 3 elements and reads them into the ax register one-by-one. PTO 5 1 2 3 4 5 6 7 8 9 .data arrayW WORD 1000h, 2000h, 3000h .code mov si, OFFSET arrayW ; si now has the offset of arrayW mov ax, [si] ; ax = 1000h add si, 2 ; increment pointer by one word mov ax, [si] ; ax = 2000h add si, 2 mov ax, [si] ; ax = 3000h Line – 2: On line two we have declared a list of 3, 16-bit unsigned integers with the name ‘arrayW’ Line – 4: Using the ‘OFFSET’ operator the offset of the first element of ‘arrayW’ from the beginning of the data segment is moved into the general purpose register ‘si’ (source index). In other words, arrayW always points to the address of the first element in the array. Line – 5: ‘[si]’ returns the contents of the memory location stored in the ‘si’ register. This value is 1000h, hence ax will now have 1000h. Line – 6: We now need to increment the pointer to point to the next element. Since the array is of type WORD i.e. 16-bit, we need to increment the offset by 2 bytes, hence we add 2 to the ‘si’ register to make it point to the second element. Line – 7: Reads the second element from memory. How to create loops Loops can be setup using the ‘LOOP’ instruction along with the cx register (which functions as a loop counter) to specify the number of iterations. The syntax is LOOP destination The execution of the LOOP instruction involves two steps: 1. Subtract 1 from ‘cx’. 2. Compare ‘cx’ with zero. 3. If ‘cx’ equals zero, execution continues with the instruction following the loop instruction. Otherwise the program branches back to the destination and the next iteration of the loop takes place. The following code is a simple loop that increments ax 5 times. mov ax, 0 mov cx, 5 doLoop: inc ax loop doLoop ; initializing ax to 0 ; intitalizing cx to 5 ; destination to be used in loop ; incrementing ax ; subtract 1 from cx, if it is not equal to ;zero jump to doLoop 6 The following example illustrates using loops and arrays together. Example for Loops The following code sample adds all the integers in an array in memory. 1 2 3 4 5 6 7 8 9 10 11 .data intarray WORD 100h, 299h, 300h, 400h .code mov si, OFFSET intarray mov cx, LENGTHOF intarray mov ax, 0 loopThing: add ax, [si] add si, TYPE intarray loop loopThing ; address of the 1st element ; initialize loop counter ; initialize ax Line – 2: Initializes an array of type WORD Line – 5: Uses the ‘OFFSET’ instruction to place the starting offset of ‘intarray’ in the register ‘si’ Line – 6: Uses the ‘LENGTHOF’ instruction to determine the length of the array i.e. the number of elements in the array. This value is copied to ‘cx’ so that it can be used to iterate through all the elements. Line – 8: The label subsequently used by the LOOP instruction indicating the beginning of the loop. Line – 9: Add the current element of the array (pointed to by si) to ax Line – 10: Important: The offset in ‘si’ has to be incremented by the size of the data type used in the array. The ‘TYPE’ instruction can be used to determine the size of one unit of the array. Thus ‘TYPE intarray’ will return 2 because a WORD is made up of 2 bytes. Thus ‘si’ will be incremented by 2 to point to the next element in the array. Line – 11: As mentioned before, the ‘LOOP’ instruction will subtract 1 from cx, compare it with zero and then determine whether to loop again or not. If cx is not zero, the program will branch back to the label loopThing. Exercise 2 Write a program that uses a loop to calculate the first ten values in the Fibonacci number sequence {1, 1, 2, 3, 5, 8, 13, …}. Initialize an empty array and write these values into the array. Use the instructions given on the next page to learn how to read values stored in memory. 7 Hints 1. You can use the following initialization myArray Word 1,1 8 DUP(0) ; 10 bytes first two elements of fibonacci series are 1 so set them as 1 manually and the rest 8 are initialized to 0. The rest 8 u have to calculate them using a loop 2. Indirect referencing can be used as a destination in the ‘ADD’ and ‘MOV’ instruction e.g. add [ax], 30h ; add 30h to the memory location pointed to by ‘ax’ How to use the Debugger to examine the contents of memory Make sure that you have successfully compiled and built your program. Then launch the debugger. Use F8 only to execute the following 2 statements of you program. mov ax, @data mov ds, ax We are now going to lift a bit of the mystery from the above two statements. The above two statements initialize the data segment i.e. telling the computer where the data lies in the memory. The register ‘ds’ now contains the starting address of the data segment; hence any offsets used in the program are in reference to the address contained in ‘ds’. Once these two instructions have been executed, Press ALT+6 to open a new window called ‘memory2 b DS: 0’ as shown in the following page. Please make sure that you have opened up memory 2 b DS window. You can also open it selecting the memory 2 label from the windows menu provided in your screen.as shown below 8 In the above window, DS = 1884. Thus the starting address in the ‘memory2’ window should be equal to DS:0000, which in this case is 1884:0000 Make sure that the value against DS register i.e. 1884 in this case is equal to starting address in the memory 2 window. If this is not the case close the memory 2 window and open it up again. Line number 15 in the program in the window above moves the offset of ‘var1’ into the register si. From the figure above, SI=000E. Thus ‘var1’ lies at an offset of 14 from the start of the data segment. You can see that in the ‘memory2’ window. The array is highlighted in the figure above. Also observe that the values are stored in little endian format. Use this window to check your values of the Fibonacci series and show it to the TA. 9 Exercise 3 Write a program using the Loop instruction with indirect addressing that copies a string from source to target, reversing the character order in the process . Use the following variables. Source Byte “ this is the source string “,0 Target Byte SIZEOF source DUP(0) Please make sure that you remove all other variables from the data segment except for these two in order to avoid difficulties while viewing the results. You have to check the output in the same manner as you did for fibonacci series. In this case your final output would show a series of following hex values as shown below. End of source start of source start of targert In the above window both source and target are showing the same sequence of hexadicmal numbers i.e. but in opposite orders. In case of source array we start at 54 and end at 67. And in case of target array we start at 67 and proceed in the opposite order. Finally Source = 54 68 69 73 20 69 73 20 74 68 65 20 73 6f 75 72 63 65 20 73 74 72 69 6E 67 Target = 67 6E 69 72 74 73 20 65 63 72 75 6F 73 20 65 68 74 20 73 69 20 73 69 68 54 If you have the following sequences appearing in the memory 2 window please call the TA and get your attendance marked. I hope you enjoyed the Lab 10