0% found this document useful (0 votes)
17 views22 pages

211 Midterm II Review

The document provides a comprehensive review of memory organization, pointers, arrays, memory allocation, and the compilation process in C programming. It explains concepts like stack and heap memory, ELF file sections, static and dynamic linking, and the role of the linker and loader. Key observations about static and dynamic linking highlight the differences in file size and memory usage between the two methods.

Uploaded by

ashalibaba123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
17 views22 pages

211 Midterm II Review

The document provides a comprehensive review of memory organization, pointers, arrays, memory allocation, and the compilation process in C programming. It explains concepts like stack and heap memory, ELF file sections, static and dynamic linking, and the role of the linker and loader. Key observations about static and dynamic linking highlight the differences in file size and memory usage between the two methods.

Uploaded by

ashalibaba123
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 22

Midterm II Review

Pointers
Memory Organization
● 1 byte = 8 bits
● Each address consist of a byte
● Range of addresses: [0, N-1], where N is a positive integer value (typically 2^32 or 2^64)
● Recall the size in bytes for an int, short, and char
○ int = 4 bytes
○ short = 2 bytes
○ char = 1 byte
● The number of address spaces a value needs corresponds to the size of bytes of its data
type
○ int x = 4 -> requires 4 address spaces
○ short y = 2 -> requires 2 address spaces
○ char ch = ‘s’ -> requires 1 address space
Pointers
● & - fetches the address of a variable
● * - dereferences a pointer (i.e retrieves the actual value its pointing to)
● A pointer is 4 bytes in a 32-bit system, 8 bytes for 64-bit system
● Format specifier for printing pointers: %p
○ But you’re essentially printing the address its pointing to
● If you set the value of a pointer, it also changes the value of what it’s pointing to
Arrays and Pointers
● Basically the same thing
● Suppose we have the array: int a[5] = {1, 2, 3, 4, 5} and a pointer: int* p = a
○ a refers to the address in memory where the array starts
○ a[1] == p[1] == *(p+1)
○ a[k] == p[k] == *(p+k)
● If I did *p = 1, then:
○ *(p+1) refers to the 2nd element of a
○ *(p+k) refers to the k+1 element of a
Memory Allocation
Program and Memory

1. Stack
a. Local variables
2. Heap
a. malloc() and free()
b. # malloc() calls = free() calls
3. Read/Write Data Segment
a. Global Variables
i. int N = 4
b. Static Variables
4. Read Only Data Segment
a. Machine instructions
b. Constant Global Variables
i. const double PI = 3.14
c. String literals
GNU Compiler Collection
Three Compilation Steps
1. Compile Step
a. Translates a C program -> assembly program
b. Steps
i. gcc -S p1.c
ii. p1.s assembly program is created
1. Set of text instructions that are used to program the processor
2. Human readable
Three Compilation Steps
2. Assemble Step

a. Translates an assembly program p1.s -> relocatable object file p1.o


b. Steps
i. gcc -c p1.s
ii. p1.o machine program (binary file) is created
1. Set of binary instructions that are used to configure and control hardware
2. Specific format -> ELF (Executable and Linkable format)
MIPS
All you really need to know is:

1. R-type instruction
a. R-type involves two registers
b. An example: add
c. Opcode will always be 000000
2. I-type instruction
a. I-type includes Intermediate value, easy to remember
b. Some examples: addi
c. Opcode will always NOT be 000000
Assemble, Link, and Load
ELF Sections
● .text: machine instructions
● .rodata: read only data (constants)
● .data: initialized global/static variables
● .symtab: stores the following:
○ Name/address locations of
○ Global variables
○ Static variables
● .rel.text: relocation info for .text section
● .rel.data: relocation info for .data section
Assemble Step
● Creates an ELF file
● Creates >= 1 relocatable object files (.o)
● Creates the symbol table in .symtab
● Remember that calls like malloc(), free(), and printf() are also entries
Linker Step
1. Symbol Resolution
a. Linker attempts to locate the same symbol with same name and section type for each
unknown address in the symbol table
2. Relocation
a. Copying from relocatable object file(s) -> executable file
i. What are we copying? .text and .data from relocatable
ii. What are we copying to? .text address locations in executable file
Loader
Ok, so now we have the executable file from the Linker step, what do we do now?

● Run the program

How? ./a.out

● Copies sections in executable file -> main memory


● Begin executing instructions in .text section

Remember this?

● At this stage, OS starts assigning memory


● To these segments
Summary Steps
Note that steps 1-4 are done by the assembler (first pass), and steps 5-6 are done by the linker (second pass)

1. Create relocatable object file (sum.o)


2. Identify symbols and update .symtab section
3. Translate assembly data to machine data and update the .data section
4. Translate assembly data to machine data and update the .text section
5. Backfills (if possible) address information in .symtab and .text sections
6. Update the .rel.text section and add entries for each unresolved symbol in the .text section
Putting it all Together: Libraries and Header
Files
Static Linking (.a extension)
Multiple related object files that are combined in a single file called a static library (or archive)

● Includes a library symbol table that lists each symbol defined by a member in the archive
that is a relocatable object file

Key Observations

● For every C program, translate C-program to relocatable


object file (.o)
● Archiver program will combine every relocatable object
file in a single archive file libc.a
○ Also allows for incremental updates
○ Suppose there’s a bug in atoi.c
○ We would translate the program to a relocatable
object file (.o)
○ Then we replace (r option) updated object file in
archive if it exists, otherwise we just add it
○ Then we update (s option) the library symbol
table
Static Linking Pt 2
Key Observations

● main2.c, vector.h, and stdio.h are compiled and assembled


into a relocatable object file main2.o
● The archiver creates a libvector.a using the addvec.o
and multvec.o
○ ar rs libvector.a addvec.o multvec.o
● Linker goes into the libc.a archive and locate the printf
symbol in the printf relocatable object file
● Linker now relocates all the instructions and data for main2,
addvec, printf in a new executable object file that is fully
linked
Dynamic Linking (.so extension)
Instead of having a copy of a function’s (like printf ) relocatable object file in each program’s shared library segment, the OS creates
ONE shared library segment that will be used by one program running in memory

Occurs after program is loaded into memory (load-time) or, when the program is executing instructions (run-time) in memory

This results in a much smaller file size compared to Static Linking, which will be shown in the next slide
Dynamic Linking Pt 2
Key Observations:

● The main2 is translated in a relocatable object file → main2.o


● We create a shared library libc.so and libvector.so
○ libvector.so → addvec
○ libc.so → printf
● Linker looks for unresolved symbols in our shared object files
● Linker identifies the location of the shared library on the file
system
○ So, the relocatable object file in the shared library
loaded into memory knows the exact location in the file
● Loader loads the relocatable object file that is in the shared
library into the shared library memory segment
● Linker performs system resolution and relocation with the
running folder → fully linked executable in memory

You might also like