Part B Out: Monday 4/20/09
Part B Due: Monday 4/27/09 11:00PM
This entire assignment is about procedure call linkages. Part A is "simply" converting your palindrome assembler program from HW2 into a subroutine. Part B is somewhat more interesting.The intention is that Part A will help you verify that you understand the procedure call material before the midterm next Monday (4/20). We will make a solution available shortly after the due date (Saturday, 6:00 PM), which is why there are no extensions on this assignment.
In HW2 your wrote a palindrome program in assembler. It was written to be amain()
main()
's are in fact subroutines, so should conform to the procedure call linkage conventions. However, the code that calls them is very robust to their misbehaving, so we didn't have to worry about that in HW2.The code distribution (below) provides you with a
main()
, written in C--, a sample solution to the HW2 palindrome question, a prologue, and an iolib.main()
reads a line of input from the terminal, calls the subroutine-ified palindrome program passing it that input, and then prints the return value (0 or 1). The palindrome program basically does just what it did before - determines whether or not a string is a palindrome. You can start from either the sample solution palindrome program (part3.s) or your own solution, as you like.Here is
main()
:char inString[256]; void main() { // we loop until the user types something that isn't a palindrome int gotOne = 1; while(gotOne) { printString("Please enter a palindrome: "); readString( inString, 256 ); gotOne = isPalindrome( inString ); // This print is a debugging aid -- when you see it, you // know isPalindrome() returned, and what it returned. // Otherwise, though, it shouldn't really be here. printInt( gotOne ); printString( "\n" ); } }and here is some output from running the solution I wrote:zahorjan@fileserver:~/cse378/09sp/hw3$ make [Compiler, assembler, linker output elided] zahorjan@fileserver:~/cse378/09sp/hw3$ cebsim pal.exe Loading Cebollita program file pal.exe Sizes: text=0000027c(636) data=00000158(344) stack=00000800(2048) heap=00000200(512) Please enter a palindrome: a+b+a a+b+a is a palindrome. 1 Please enter a palindrome: Madam I'm Adam. Madam I'm Adam. is a palindrome. 1 Please enter a palindrome: the quick brown fox the quick brown fox is not a palindrome. 0 Halt instruction(Note that a
makefile
is part of the distribution.)To convert a palindrome implementation to a procedure that can be called from
main()
, and results in this output, you need to:
- Rename the entry point of the subroutine from
main
toisPalindrome
.- Insert the procedure entry code to do the callee side work to set up the stack frame on entry to the subroutine.
- Insert the procedure return code just before returning to the mainline.
- Don't forget to
return
the value that in HW2 we were leaving in $10, as the mainline is expecting a returned value.- Implement the call(s) to
printString(char*)
to print the output lines that appear in the sample output, but obviously aren't printed bymain()
. (Hint: they're in red.) (printString(char*)
is implemented iniolib.s
. You shouldn't have to read that code to invoke it.)
Debugging is painful, because the debugger is operating at the machine/assembler level, and it's unlikely you'll be thinking of the program that way. (After all, half of it is written in C--.) My totally serious advice is this: don't make any mistakes. Review your code carefully before running, with the goal of having it work the first time you try it. (If it doesn't work, I'd start the debugging process by looking at the code again, rather than using breakpoins, say, in the simulation. Those are a last resort.)Here is a list of things to look out for, to help you achieve a "worked first time" implementation:
- In HW2 we used register names like $8, $9, and $10. In this assignment it's going to be more natural to start using symbolic names, like $t0, $t1, and $t2. Remember that both styles are names for the same 32 registers, and so be very, very careful when using symbolic names that you're not unintentionally wiping out some register that, for instance, you refer to elsewhere in the program as $7.
- My guess is you're going to want to write a line of assembler something roughly like this, as part of trying to call
printString()
:Nothing even remotely like that can work, in assembler.ori $t0, $0, "this is a string literal"
A literal value, like this string, should be allocated in the static data region - i.e., should be allocated (and initialized) in the
.data
portion of the.s
file. At that point, using it is just like using a static variable (it's just that, being a literal, no code is every going to assign a new value to it).
- Remember that in C (and C--), a string is a
char*
, and a
char*
is a pointer. This means you want to pass the address of the string as the argument toprintString
.
- Remember that when you call
printString
, its code will use the same set of 32 registers you've been using. That means that whenprintString
returns to your code, any register (except for $gp, $fp, $sp, and $ra) could have basically have a random value in it.If there is a value in a register that you want to still have after the call to
printString
, you need to "spill" (store) that value into memory. You do that by allocating some space on the stack before the call, and usingsw
to save the register there. When the call returns, you fetch the saved value off the stack, back into the register, and free the stack memory (by increment $sp).
Note: the distributed solution to the HW2 palindrome problem makes most sense when compared against the implementation written in C, and available from the HW2 sample solution.
To get the details on the Cebollita procedure call linkage:
- The Cebollita procedure call handout.
- The Cebollita C-- compiler knows how to generate assember that follows the Cebollita procedure call linkage. Write( or find) a C-- program that is a, or invokes a, procedure, compile it, and look at the
.s
file that is generated. (E.g., look atmain.s
. To see it, you'll have to issue a compile command by hand, becausemake
deletesmain.s
as it finishes up.)
Online: https://catalysttools.washington.edu/collectit/dropbox/zahorjan/5621