Skip to main content

Exercises 8.6 Programming Exercises

1.

Enter the program in Listing 8.5.1 and trace through the program one line at a time using gdb. Use the n command, not s or si. Keep a written record of the pc register at the beginning of each line. How many bytes of machine code are in each of the C statements in this program? Note that the addresses you see in the pc register may differ from the example given in this chapter.

Hint

Use the i r command

Answer

This can vary, depending on different versions of the compiler, etc. This is an exercise on using gdb so you can become comfortable with it for when you will actually need it to find your errors. It is also an excellent learning tool.

2.

As you trace through the program in Exercise 8.6.1 stop on line 21:

wye += *ptr;

We determined in the example above that the r4 register is used for the variable wye. Determine which register is being used for wye in your instance of the program. Inspect the registers.

  1. When your program stops at this C statement, what is the address of the first instruction that will be executed when you enter the n command?

  2. How will the register that holds the wye value change when this statement is executed?

  3. How many bytes of the program does this statement is use?

Hint

To determine the number of bytes used by this C statement, subtract the value of the pc before it is executed from the value of the pc after you use the n command to execute the statement.

Answer

The contents of the register should be one less than the integer you entered when the program prompted you. The C statement uses 12 bytes of program memory.

3.

Modify the program in Listing 8.5.1 so that a register is also requested for the ex variable. Were you able to convince the compiler to do this for you? Did the compiler produce any error or warning messages? Why do you think the compiler would not use a register for this variable.

Answer

The program uses the address of ex, &ex, so the variable must be located in memory.

4.

Use the gdb debugger to observe the contents of memory in the program from Exercise 2.16.2. Verify that your algorithm creates a null-terminated string without the newline character.

5.

Write a program in C that allows you to determine the endianess of your computer.

Hint

Use unsigned char* ptr.

Solution
/* endian.c
 * Determines endianess. If endianess cannot be determined
 * from input value, defaults to "big endian"
 * 2017-09-29: Bob Plantz
 */

#include <stdio.h>

int main(void)
{
  unsigned char *ptr;
  int x, i, bigEndian;

  ptr = (unsigned char *)&x;
   
  printf("Enter a non-zero integer: ");
  scanf("%i", &x);
   
  printf("You entered %#010x and it is stored\n", x);
  for (i = 0; i < 4; i++)
    printf("   %p: %02x\n", ptr + i, *(ptr + i));

  bigEndian = (*ptr == (unsigned char)(0xff & (x >> 24))) &&
            (*(ptr + 1) == (unsigned char)(0xff & (x >> 16))) &&
            (*(ptr + 2) == (unsigned char)(0xff & (x >> 8))) &&
            (*(ptr + 3) == (unsigned char)(0xff & x));
  if (bigEndian)
    printf("which is big endian.\n");
  else
    printf("which is little endian.\n");

  return 0;
}
6.

Modify the program in Exercise 8.6.5 so that you can demonstrate, using gdb, that endianess is a property of the CPU. That is, even though a 32-bit int is stored little endian in memory, it will be read into a register in the “proper” order.

Hint

Declare a second int that is a register variable; examine memory one byte at a time.

Solution
/* endianReg.c
 * Stores user int in memory then copies to register var.
 * Use gdb to observe endianess.
 * 2017-09-29: Bob Plantz
 */

#include <stdio.h>

int main(void)
{
  int x;
  register int y;
   
  printf("Enter an integer: ");
  scanf("%i", &x);
   
  y = x;
  printf("You entered %i\n", y);

  return 0;
}