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.
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.
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?How will the register that holds the
wye
value change when this statement is executed?How many bytes of the program does this statement is use?
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.
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.
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.
Use unsigned char* ptr
.
/* 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.
Declare a second int
that is a register variable; examine memory one byte at a time.
/* 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; }