Monash University > School of Computer Science and Software Engineering > CSE1303 > Part B > Tutorials > Tutorial B6
This tute covers material from lectures B14 to B16.
Attempt the questions marked (*) like this before the tutorial. If you have specific questions about unmarked questions, you can ask the tutor about them during the tutorial.
What elements of the C language help to achieve the above goals?
Which of the list of reasons from the previous questions does this convention satisfy? Which does it fail to provide?
min: subu $sp, $sp, 8
sw $ra, 4($sp)
sw $fp, 0($sp)
move $fp, $sp
subu $sp, $sp, 4
lw $t0, 8($fp)
lw $t1, 12($fp)
bge $t0, $t1, one
lw $t0, 8($fp)
sw $t0, -4($fp)
j end
one: lw $t0, 12($fp)
sw $t0, -4($fp)
end: lw $v0, -4($fp)
addu $sp, $sp, 4
lw $fp, 0($sp)
lw $ra, 4($sp)
addu $sp, $sp, 8
jr $ra
Add comments to the code, and suggest what this function does and how it might be called. Suggest the C code that would have generated this function.
Remark on the symmetry of the function entry (up to the first blank line) and exit (from the label end). In particular, comment on the statement, "Every subtract applied to the stack pointer has an equal and opposite addition later in the code."
Is this order necessary? In other words, would it be possible to have the last parameter at 8($fp) instead, and the second-last at 12($fp), and so on (provided that all functions are changed to agree with this new convention)?
# y = func(x);
subu $sp, $sp, 4 # one argument.
lw $t0, x # first argument is x
sw $t0, 0($sp)
jal func # call function
sw $v0, y # store result
Assuming that x and y are valid labels, what is wrong with this code?
What is likely to happen to the program when it runs this code? What if this code were in a loop which repeats 1 million times?
How would main's stack diagram differ if main were coded the same way as other functions? Would this complete main's (normally partial) stack frame? What does this tell you about the contents of the part of the stack that exists before main begins (the part that we always draw diagonal lines in)?
#include <stdio.h>
#include <stdlib.h>
/* Prototype for isdigit() function. */
int isdigit(const int c);
int atoi(const char *s);
int main()
{
int n;
char s[20];
printf("Enter a number: ");
/* Read string. */
fgets(s, 20, stdin);
/* Find number at start of string. */
n = atoi(s);
printf("Number is: %d.\n", n);
exit(0);
}
/* atoi(s): extract the integer value
* encoded in ASCII at the beginning of
* string s, and return it. Radix is 10. */
int atoi(const char *s)
{
int sign = 1;
int result = 0;
int digit;
if (*s == '-')
{
/* Leading minus sign. */
sign = -1;
s++;
}
else if (*s == '+')
{
/* Leading plus sign. */
s++;
}
/* Stop at end of string. */
while (*s != '\0')
{
/* Pass character to isdigit as an int,
to preserve stack alignment. */
if (!isdigit((int) *s))
{
/* Also stop if non-digit found. */
break;
}
/* What value does this digit have?
* This works because in ASCII, '0' (48) to
* '9' (57) are contiguous. */
digit = *s - '0';
/* Append this digit to our running total. */
result = result * 10 + digit;
/* Next character. */
s++;
}
/* Return result multiplied by sign. */
return result * sign;
}
Assume that printf and fgets are implemented using system calls as usual, and that isdigit is another function which obeys the normal function calling convention.
Draw a stack diagram for main.
Draw the stack as it appears on entry to atoi.
Draw the stack as it appears on entry to isdigit (assume that this function has no local variables).
Translate the above two functions (main and atoi) into MIPS. Try to make your translation as faithful as possible.
Suggest a method for turning a recursive C function into a non-recursive C equivalent, with the help of a stack data structure. You are permitted to use goto statements in your code, though you should make an effort to clean them up afterwards.
Under what circumstances could you dispense with the stack entirely?
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b);
int main()
{
int x;
int y;
printf("Enter two numbers: ");
scanf("%d%d", &x, &y);
printf("Greatest common divisor is %d.\n", gcd(x, y));
exit(0);
}
int gcd(int a, int b);
{
if (b == 0)
{
return a;
}
else
{
return gcd(b, a % b);
}
}
Draw a stack diagram for this program, at the point where the stack is the deepest, for the input x = 84, y = 30. Mark the stack frames on your diagram.
Translate this program into MIPS. Try to make your translation as faithful as possible.
Last modified 2002-02-04