CMPT 295: Unit - Machine-Level Programming
- Lecture 8 – Introduction
- Compilation process: C -> assembly code -> machine level code
Last Lecture
- Most fractional decimal numbers cannot be exactly encoded using IEEE floating point representation -> rounding
- Denormalized values
- Condition: exp = 0000…0
- 0 <= denormalized values < 1, equidistant because all have same 2E
- Special values
- Condition: exp = 1111…1
- Case 1:
- Case 2:
- Condition: exp = 1111…1
- Impact on C
- Conversion/casting, rounding
- Arithmetic operators:
- Behaviour not the same as for real arithmetic => violates associativity
Today’s Menu
- Introduction
- C program -> assembly code -> machine level code
- Assembly language basics: data, move operation
- Operation leaq and Arithmetic & logical operations
- Conditional Statement – Condition Code + cmovX
- Loops
- Function call – Stack
- Array
- Buffer Overflow
- Floating-point data & operations
What could these 32 bits represent?
What kind of information could they encode?
00011000111011001000001101001000
Answer:
- Aside from characters, integers or floating point numbers, etc…
- Review: We saw that all modern computers, designed based on the von Neumann architecture, store their programs in memory
- Data and instructions of our C program are in main memory together (but in different locations)
- So, these bits could represent code, for example:
- Assembly code:
sub $0x18, %rsp
- Machine code:
48 83 ec 18
- Assembly code:
C program in memory?
We have just spent a few lectures looking at how our data can be represented as a series of 0’s and I’s, now …
- Question: How does our C program end up being represented as a series of 0’s and 1’s (i.e., as machine code)?
- Question: Then, how does our C program (once it is represented as a series of 0’s and 1’s) end up being stored in memory?
- Question: Then, how does our C program (once it is represented as a series of 0’s and 1’s and it is stored in memory) end up being executed by the microprocessor (CPU)?
Demo – C program: sum_store.c
- Question: How does our C program end up being represented as a series of 0’s and 1’s (i.e., as machine code)?
Let’s answer these questions with a demo
Turning C into machine code - gcc
The Big Picture (transcriber’s note: each step depends on the last; this is implied in the diagram):
- C program (.c) -> sum_store.c
- C Preprocessor:
gcc -E sum_store.c > sum_store.i
- C Preprocessor:
- Pre-processed Source (.i) -> sum_store.i
- C Compiler
gcc -Og -S sum_store.i
, orgcc -Og -S sum_store.c
- C Compiler
- Assembly Program (.s) -> sum_store.s
- Assumbler:
gcc -g -c main.s sum_sotre.s
- Assumbler:
- Object (.o) -> sum_store.o
- Linker:
gcc -o ss main.o sum_store.o
- Linker:
- Executable ->
ss
- Loader:
./ss 5 6
. - Disassemlber:
objdumb -d ss
(gdb/ddd debugger). This will write a disassembled object file which is the only one which is a mix between plain text and data.
- Loader:
- ISA - Instruction Set Architecture
- Computer Executes It
- CPU
- Memory
Snapshot of compiled code
- C code:
*dest = sum;
- Store sum in memory designated by pointer dest
- Assembly code:
movq %rax, (%rbx)
- Move an 8-byte value to memory
- Quad words in x86-64 parlance
- Operands:
sum
: register%rax
dest
: register%rbx
*dest
: memoryM[%rbx]
- Move an 8-byte value to memory
- Machine code (1’s and 0’s):
0x40059e: 48 89 03
- 3-byte instruction
48
stored at address0x40059e
89
stored at address0x40059f
03
stored at address0x4005a0
Fetch-Execute Cycle
Terms:
- PC - program counter
- Defn: register containing address of instruction of ss that is currently executing
- IR - instruction register
- Defn: register containing copy of instruction of ss that is currently executing
Question: How does our C program (once it is represented as a series of 0’s and 1’s and it is stored in memory) end up being executed by the microprocessor (CPU)?
Answer: The microprocessor executes the machine code version of our C program by executing the following simple loop:
DO FOREVER:
- fetch next instruction from memory into CPU
- update the program counter
- decode the instruction
- execute the instruction
Summary
- Review: von Neumann architecture
- Data and code are both stored in memory during program execution
- Question: How does our C program end up being represented as a series of 0’s and 1’s (i.e., as machine code)?
- Compiler: C program -> assembly code -> machine level code
- gcc: 1) C preprocessor, 2) C compiler, 3) assembler, 4) linker
- Question: How does our C program (once it is represented as a series of 0’s and 1’s) end up being stored in memory?
- When C program is executed (e.g. from our demo: ./ss 5 6 )
- Question: How does our C program (once it is represented as a series of 0’s and 1’s and it is stored in memory) end up being executed by the microprocessor (CPU)?
- CPU executes C program by looping through the fetch-execute cycle
Next Lecture
- Introduction
- C program -> assembly code -> machine level code
- Assembly language basics: data, move operation
- Memory addressing modes
- Operation leaq and Arithmetic & logical operations
- Conditional Statement – Condition Code +
cmov*
- Loops
- Function call – Stack
- Array
- Buffer Overflow
- Floating-point operations