CS31 Weekly Lab: Week 5

Week 5 lab topics:

  1. writing IA32 in .s file and compiling into executable with gdb
  2. structs in C, arrays of structs, linked lists in C
  3. tools for examining binaries: strings, gdb and ddd, objdump, nm, ...

Start up a terminal and ssh into your CS machine:
  ssh -Y you@your_machine.cs.swarthmore.edu
Once remotely connected to cs, you can start other xterms on our system by:
   $ xterm &
Then create a week05 subdirectory in your weeklylab subdirectory and copy over some files:
    cd cs31/weeklylab		
    pwd
    mkdir week05
    ls
    cd week05
    pwd
    cp ~newhall/public/cs31/week05/* .
    ls

Writing IA32 Assembly and compiling with gdb
One way to verify if you have written correct assembly code is to code it up in a .s file, and then compile it into an executable program using gcc. One way to do this is to have a main function written in C that then makes calls to hand written assembly code functions. To compile:
 gcc -m32 -o program main.c assemblyfile.s
Let's open main.c and crazy.s and see what it is doing.

Now let's add some code to crazy.s to get it to do something with the two parameter values, compile it and try it out.

Remember to use the IA32 Cheat Sheet (available at the bottom of the class web page) when reading or writing IA32 code.

C Structs
In structs.c is a program that uses C structs.

C is not an object oriented language, so it does not have objects. It does, however, have a way of grouping a set of values together in a single type, which is similar to the data parts only of objects.

In C you can define a new structured type, a struct, in many ways. Typically structs are defined in .h files or in .c files outside of function bodies (similar to where #defines, function prototypes, and global variables are defined). Here is one way to define a new struct type associated with student data (the type name is "struct student"):

struct student {
    char name[50];
    int  age;
    int  year;
    float  gpa;
};
In your program, you can then declare variables whose type is struct student or struct student * (a pointer to a struct student). To access individual fields in a struct, use dot "." notation if the variable's type is "struct student" and right arrow notation "->" if a variable's type is a "struct student *". Here are some examples:
struct student s;
struct student *sptr;

# you need to think very carfully about the type of each field
# when you access it (i.e. name is an array of char, age is an int ...
strcpy(s.name, "Freya");
s.age = 18;
s.year = 2016;
s.gpa = 4.0;

sptr = malloc(sizeof(struct student));
if(!sptr) { ... error handling code ... }
sptr->age = 20;
sptr->year = 2015;
sptr->gpa = 3.2;
strcpy(sptr->name, "Lars"); 

You can also declare static or dynamic arrays of structs or arrays of pointers to structs or ... (you need to think very carefully about type). Here are some examples:

struct student students[36];   // an array of 36 student structs
struct student *students2;    // a dynamically allocated array of student 
                              // structs (each bucket holds a struct student)
struct student *students3[36];  // statically declared array of student struct*
                                // (each bucket holds a (struct student *))
Examples of their use:
students[i].age = 21;   // the ith bucket stores a student struct
                        // use dot notation to access its fields

// dynamically allocate array of student structs
students2 = malloc(sizeof(struct student)*10);   

students2[3].year = 2013;   // each bucket in this array is a student struct
                            // use dot notation to access its fields

// each bucket of students3 stores a pointer to a student struct
students3[0] = malloc(sizeof(struct student));  

students3[0]->age = 21;   // dereference the pointer to the struct in bucket 0

Linked Lists in C

You can also define self-referential structs in C (structs with fields whose type is a pointer to the struct type). This is how you would define a node for a linked list for example:

struct node {
  int data;
  struct node *next;
};
Then you could use instances of this struct type to create a linked-list:
struct node *head, *temp;

head = NULL;  // an empty linked list

head = malloc(sizeof(struct node));
if(!head) { // some error handling code ... }   // !head is == (head != NULL)
head->data = 10;
head->next = NULL;

// add 5 nodes to the head of the list:
for(i = 0; i < 5 i++) {
   temp = malloc(sizeof(struct node)); 
   if(temp == NULL) {  // some error handling code ... } 
   temp->data = i; 
   temp->next = head; 
   head = temp;
}

TODO:

We are going to compile and run structs.c, and see what it is doing.

Next open up structs_quiz and work with a classmate to answer the questions. We will go over these together.

Tools for examining binary files
We are going to look at some tools for examining binary files:
  1. strings: dumps all the strings in a binary file
      strings a.out
    
  2. nm (or objdump -t) to list symbol table contents
      nm --format sysv a.out          # dump the symbol table in the a.out file
      objdump -t  a.out               # dump the symbol table in the a.out file
    
  3. ddd and gdb: examine runtime state, registers, individual instructions, memory contents

    See the week 4 lab page for more information and examples. Here are a summary of some of the most useful commands:

      ddd a.out
      (gdb) break main
      (gdb) run
      (gdb) disass
      (gdb) break *0x1234         # set a break point and memory address 0x1234
      (gdb) cont
      (gdb) ni                    # execute the next instruction
      (gdb) si                    # step into a function call (step instrution)
      (gdb) info registers
      (gdb) p  *(int *)(0x8870)   # print out the value of an int at addr 0x88760
      (gdb) p %eax
    
Some more information on Tools for examaning .o, .so, and a.out files
Some more information on gdb and ddd: gdb Guide

Figure 3.30 on p.255 of the textbook lists gdb commands.