COMP15111 – 2014 – Javier Navaridas/Richard Neville/Milan Mihajlovic – Lab 4: Methods and Control Structures 10 4 COMP15111 Lab 4 – Methods and (more) Control Structures Duration: 1 lab session 4.1 Aims To practise converting Java control structures into ARM assembly code and experience stack operations. 4.2 Learning Outcomes On successful completion of this exercise a student will: – have encoded a Java method in various styles using ARM code – have encoded Java conditional evaluation operations (&& and ||) using ARM code 4.3 Summary Translate a Java program derived from an example in the Java course-unit (AgeHistory2) into ARM code. The program consists of calls to a method, that uses parameters and local variables, and contains a while statement and an if-then-else statement, both of which use conditional Boolean operations (&& and ||). Each lab exercise has the usual deadline at the end of your scheduled lab session. If you attend the lab you will, if you need it, get an automatic 7-day extension. This is so that you can get help in the lab and then have some time to make use of that help to complete the exercise. This will be the case for all your labs for this course-unit. Remember that you must use “submit” in the usual way to show that you completed your work by the (extended) deadline. If you decide to complete the exercise after our labs shut in the evening, it is your responsibility to make sure that you can “submit” remotely. 4.4 Description As usual, you will need to copy the starting code to your lab directory and run KMD: > cd COMP15111/ex4 > cp /opt/info/courses/COMP15111/Lab/ex4/* . > start komodo 15111& There is a file, “part1.s”, that contains the Java program as a set of comments, with some ARM code. The ARM code deals with the output and a simplified version of the rest of the program which uses the stack to pass parameters: – For part 1 you will need to understand the data structure and improve the efficiency of its use. – In part 2 you need to tidy up the code by abstracting some repeated sections into a method of your own. – The conditions in the “while” and “if” statements have not been properly translated - for part 3 you are supposed to correct this. Remember, when you come to run your ARM program in KMD, to open the “Features” window to view the output and to use the “clear” button before each run, as in exercises 2 and 3. 4.4.1 Part 1: Using the stack for parameters and local variables For this part, you should edit the file you have been given, “part1.s”. This code passes the parameters to the method printAgeHistory by pushing them onto the stack – one at a time. The method is then called with a BL instruction. Finally the parameters are removed again; what would happen if this was not done? Inside the method some working registers are needed but these may already hold important values. The working registers are therefore stacked before they are modified (e.g. at the start of the method); they must also be restored at the end of the method, before returning to the calling code. The stack has been set up for you at the start of the program by allocating a space in memory and pointing the Stack Pointer (SP a.k.a. R13) at an appropriate address. Use the memory pane (bottom right) – or open a New Memory Window – to view the memory implementing the stack as you step through the code. The stack pointer (SP/R13) address is highlighted in purple. Observe how the stack grows and shrinks as the code proceeds. This may help clarify your understanding of how the machine works. The code contains some deliberate inefficiencies; for example it is longer (and slower) than is necessary. COMP15111 – 2014 – Javier Navaridas/Richard Neville/Milan Mihajlovic – Lab 4: Methods and Control Structures 11 TASK: Modify the code around the method call – inside and outside if you feel it’s appropriate – to improve the implementation without changing the stack-based mechanism. Be careful that your parameters are all passed in the expected order. There is another file, “AgeHistoryPart1.java”, that contains a version of the Java program with these simplified conditions – you can compile and run this in the usual way to see how your completed ARM program should behave if you have done everything correctly. 4.4.2 Part 2: Optimising parameter passing Notionally parameters are passed on the stack in this manner. With a processor with ‘many’ registers (such as – arguably – ARM) some parameters may be passed in registers. This can be considerably more efficient (what are the savings?) and, as the ‘typical’ number of method parameters is small, works quite well. TASK: Copy your code from “part1.s” to a new file – “part2.s” – and modify it to use registers for its method parameters. 4.4.3 Part 3: Nesting method calls The code which prints the date occurs (with a slight variation) in three places in the code. This will make it more difficult to modify – e.g. if a customer wanted the numbers in a different order – because that is their local convention. TASK: Create a prints the date method. Make a new copy of your program (“part3.s”) and extract the relevant code as a method in its own right; you may pass parameters by whatever mechanism you prefer. Invoke it from the three separate places; check carefully that the correct parameters are passed each time and you do not corrupt any values in use. Note that these calls will be nested inside printAgeHistory and you may need to check that you are not corrupting more of your register states. Hint: if you have problems go back and step through the code observing the register states. 4.4.4 Part 4: Improving the translation of the conditions Copy your answer for part 3 to a new file, “part4.s” i.e. cp part3.s part4.s and use this new file to create your answer to this part. TASK: Extend the function of your program by adding in the code for the extended comparisons which were commented out. These occur in two places and are marked “for part 3 . . . ” in the file. There is another file, “AgeHistoryPart2.java”, that contains the Java program with the correct conditions. If you want to, you can compile and run this in the usual way to see how your completed ARM program should behave if you have done everything correctly. Remember the unusual thing about && and ||, compared to most other Java operators, is that you don’t evaluate the whole of the expression if the first part of it tells you the answer e.g. for: a