0% found this document useful (0 votes)
29 views3 pages

Ca 0

The document describes the process of running a high-level program on a computer. It begins with compiling source code to assembly code, assembling to object code, and linking object files and libraries together to create an executable. The memory is divided into segments for text, data, stack, and OS/I/O. Assembly directives guide allocation and initialization of variables and sections. Compilation, assembly, linking, and loading steps are explained.

Uploaded by

Umang Garg
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)
29 views3 pages

Ca 0

The document describes the process of running a high-level program on a computer. It begins with compiling source code to assembly code, assembling to object code, and linking object files and libraries together to create an executable. The memory is divided into segments for text, data, stack, and OS/I/O. Assembly directives guide allocation and initialization of variables and sections. Compilation, assembly, linking, and loading steps are explained.

Uploaded by

Umang Garg
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/ 3

- Process run a high level program on computer can be broken into following steps -

- **High Level program** is compiled by *compiler* => **Assembly Code**


- **Assembly Code** is translated by *Assembler* => **Object Code**
- **Object Code** + **Library code/Object from other files** is linked together by
*Linker* => **Executable**
- **Executable** is loaded by *Loader* in => Memory
- Once in the memory, the processor PC can be pointed to the starting address of the program code
to start execution.
### The Memory Map
- With 32-bit addresses, the RISC-V address space spans 4 GB
- Word address are multiples of 4 and range from 0x0000_0000 to 0xFFFF_FFFC
- Memory Maps divides the avalible memory in 5 segments ->
- the text,
- global data,
- dynamic data segment,
- exception handler
- OS, which include I/O segment
* RISC-V does not define a specfic memory map, but
* Exception handler are typically placed at either low or high addresses
* user (system designer?) can define where the text, memory I/O, stack and global data are
placed.
* This is to allow flexibility, specially for smaller handheld devices where the complete 5 GB
might be populated.
- Example memory map -
```mono
Address Segment
|-------------------------|
0xFFFF_FFFC | |
| Operating System & IO |
0xC000_0000 | |
|-------------------------|
0xBFFF_FFF0 | Stack (grows down) | <- sp
| Dynamic Data |
0x1000_1000 | Heap (grows up ) |
|-------------------------|
0x1000_0FFC | |
| Global Data | <- gp (0x1000_0800)
0x1000_0000 | |
|-------------------------|
| |
| Text |
0x0001_0000 | | <- PC
|-------------------------|
| |
| Exception Handlers |
0x0000_0000 | |
|-------------------------|
```
**The Text Segment**
- Stored the machine language user program
- It also includes any literals (constants) and read-only data
**The Global Data Segment**
* Holds global variable
* These are loaded in memory before the program starts
* All functions can access these variables
* Access is provided by having the `gp`, global pointer point to the middle of this segment, and with
12-bit signed offset, complete region can be accessed
**The Dynamic Data Segment**
- This segment contains the stack and heap
- Data in this is not know at start of the program, it is populated during run time, thus its called
Dynamic Data
- Stack is used by programs to store local variable. Save/Restore between function calls. Pass
arguments
- When the program starts, OS set the SP to the bottom of the stack, 0xBFFF_FFFF here.
- Heap store the data that the program allocated during run-time. `malloc` in C/C++, `new` in Java
- Heap and Stack grow towards each other, if they intersect, data corruption would occurs. Memory
allocator prevents this, and issues out-of-memory errors, if no more space is available.
**The Exception Handler, OS, and I/O Segments**
- Lowest part is revered for exception handler and boot code, that is run at start-up
- Highest part is reserved for operating system and memory-mapped I/Os
### Assembler Directives
- Assembler directives are keyword used in assembly programs to guide the assembler in allocating
& initializing global variable, defining constants, differentiating between code and data.
* The `.data`, `.text`, `.bss`, `.rodata` are assembler directives that tell assembler to places
proceeding data/code in global, text, BSS, or read-only data segments.
* BSS -> Block Started Symbol, this is initially a keyword to allocate a block of
uninitialized data. Now, most OS initialize data in BSS segment to 0.
- Common assembler directives -
| Assembler Directive | Description |
| ------------------- | --------------------------------- |
| `.text` | Text section, code & constants
| `.data` | Global data
| `.bss` | Global data initialized to 0
| `.section .foo` | Section named `.foo`
| `.align N` | Align next data/instruction on 2^N-byte boundary
| `.balign N` | Align next data/instruction on N-byte boundary
| `.globl sym` | Label sym is global
| `.string "str"` | Store string "str" in memory
| `.word w1, w2, ... wN` | Store N 32-bit values in successive memory words
| `.byte b1, b2, ... bN` | Store N 8-bit values in successive memory bytes
| `.space N` | Reserve N bytes to store variables
| `.equ name, constant` | Define a symbol name with value constant
| `.end` | End of assembly code

### Compiling
- Compiler translates high-level code into assembly language code.
- GCC by default produces the final executable, but we can stop it at compile step, resulting in
assembly file, as -
```
gcc -O1 -S prog.c -o prog.s
```
- `-S` instructs to compile, but not assemble or link
- `-O1` tells compiler to do basic optimization
### Assembling
- An assembler convert assembly language code to object file
- GCC can create object file from either .c or .s code
```
gcc -c prog.s -o prog.o # From assembly
gcc -O1 -g -c prog.c -o prog.o # From C
```
- `-g` says to include debug symbols
- Assembler dose 2 passes over the assembly code
- During 1st pass, its assigns address to all the instructions and finds all the symbols and
label, keeping them in a symbol table.
- On 2nd pass, assembler produces machine code, Address for label and taken from symbol
tables
- The machine language code and symbol table is stored in object file
- We can disassemble object file using `objdump` command to see assembly code beside machine
code
```
objdump -S prog.o
```
* If the code was compiled with `-g` option (debug symbols enabled), the dump will have original C
code interspersed between assembly code
* We can also get symbol table, as
```
objdump -t prog.o
```
- In above dumps, as the program is not yet linked, some address would be invalid and would be
updated once object code go through linker.
### Linking
- Linker combines all the object file and startup code (used to setup stack/heap/etc) into one
machine language executable and assign address to global variables.
- The linker relocates the data and instructions in object files so that they are not all on top of each
other.
- Invoke GCC to link object file -
```
gcc prog.o -o prog
```
- We can disassemble the executable with -
```
objdump -S -t prog
```
### Loading
- The OS loads a program by reading the text segment of the executable file from a storage device
into the text segment of memory. The operating system jumps to the beginning of the program to
begin executing.

You might also like