Transcript C1_tour
מבוא לטכנולוגיות מחשב
מבוא
ובו נסקור את המסלול המפרך שתוכנית עוברת
במחשב עד לביצוע.
מבוסס על פרק 1של
& Computer Systems – a programmers perspective / Bryant
O’hallrron
...נתחיל מההתחלה
#include <stdio.h>
int main()
{
printf(“hello world”);
}
–2–
ייצוג ASCII
כל תו מיוצג על ידי בית ( 8סיביות) .כלומר יש 256תווים אפשריים.
e
d
u
l
c
n
i
#
101
100
117
108
99
110
105
35
...
1101001
00100011
קובץ אשר נכתב לפי הקידוד של ASCIIנקרא קובץ טקסט .כל
השאר – קבצים בינאריים.
––3
מה עכשיו ?
צריך לתרגם את hello.cלסדרת פקודות שהמחשב מבין – שפת
מכונה.
זה תפקידו של המהדר ):(compiler
gcc –o hello hello.c
דגל –oמאפשר לציין
את שם קובץ הריצה
)- (executable
” "helloבמקרה זה.
––4
המהדר
. כל אחד מופעל על ידי תוכנית נפרדת,ארבעה שלבים
hello.c
Source
program
(text)
Prehello.i Compiler hello.s
processor
(cc1)
(cpp)
Modified
source
program
(text)
Text
Assembly
program
(text)
printf.o
Assembler
(as)
–5–
hello.o
Relocatable
object
programs
(binary)
Linker
(ld)
hello
Executable
object
program
(binary)
Binary
שלב :1עיבוד מקדים
):cpp (preprocessor
מחבר את הכול לקובץ טקסט אחד >#include <...
מבצע הוראות preprocessing
#ifdef ... #endif
מעלים הערות /* ... */
מתקבל קובץ יחיד עם " Cטהור".
hello.i
––6
שלב : 2תרגום
הידור – תרגום לשפת assembly
בשפה זאת כל שורה מייצגת פקודה 'נמוכה' אחת שהמחשב תומך
בה.
שפה משותפת לכל השפות העיליות.
תוכניות ב ...,Pascal ,C++ ,Cכולן יתורגמו ל assembly
לא לכל המחשבים ("מכונות") יש אותה שפת מכונה.
שפת מכונה נקראת )Instruction Set Architecture (ISA
שפת המכונה של Intelנקראת IA-32
––7
חידה
מהי קבוצת הפקודות הבסיסיות הקטנה ביותר איתה ניתן לקבל
פונקציונליות מלאה ?
תשובה :פקודה אחת מספיקה...
בפועל משתמשים במספר מאות.
קיים קורס בטכניון בשם 'חישוביות' העוסק בשאלות מסוג
מה ניתן לחשב ?
מה המכונה הפשוטה ביותר שיכולה לחשב את כל מה שניתן לחשב ?
––8
כמה פקודות ?
מחשבי Sun, Mac,Alphaמשתמשים באוסף קטן של פקודות
טכנולוגיה (ואידיאולוגיה) הנקראים
)Reduced Instruction Set Computer (RISC
מחשבי PCמשתמשים בקבוצה גדולה של הוראות
טכנולוגיה (ואידיאולוגיה) הנקראים
)Complex Instruction Set Computer (CISC
––9
מבנה פקודה
פקודה נראית באופן הבא:
result
operand2
מיקום תוצאה (רק
חלק מהפקודות)
פרמטר
שני
opcode
operand1
קוד של
הפקודה
פרמטר
ראשון
נניח ש R1,R2,R3הם שמות של רגיסטרים ("אוגרים") או כתובות בזיכרון
הראשי.
R3
add R1 R2
000001 000110 010111
0001
– – 10
.file "hello.c"
.rodata
gcc –s hello.c
.
string "hello world"
.
text
hello.s מייצר קובץ
section
.
.LC0:
.globl main
type main, @function
.
שם של
רגיסטר
main:
pushl %ebp
movl
%esp, %ebp
subl
$8, %esp
andl
$-16, %esp
movl
$0, %eax
addl
$15, %eax
addl
$15, %eax
shrl
$4, %eax
sall
$4, %eax
subl
%eax, %esp
subl
$12, %esp
push
move
subtract
and
move
R1
R2, R1
M[1], R2
M[2], R2
M[0], R3
pushl $.LC0
call
addl
printf
$16, %esp
leave
פקודות
ret
.
size main, .-main
.
section
.
ident "GCC: (GNU) 3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)"
– 11 –
.note.GNU-stack,"",@progbits
אופרנדים
)(פרמטרים
של הפקודה
.file "hello.c"
.rodata
gcc –s hello.c
.
string "hello world"
.
text
hello.s מייצר קובץ
section
.
.LC0:
.globl main
type main, @function
.
שם של
רגיסטר
main:
pushl %ebp
movl
%esp, %ebp
subl
$8, %esp
andl
$-16, %esp
movl
$0, %eax
addl
$15, %eax
addl
$15, %eax
shrl
$4, %eax
sall
$4, %eax
subl
%eax, %esp
subl
$12, %esp
pushl
movl
subl
andl
movl
%ebp
%esp, %ebp
$8, %esp
$-16, %esp
$0, %eax
pushl $.LC0
call
addl
printf
$16, %esp
leave
פקודות
ret
.
size main, .-main
.
section
.
ident "GCC: (GNU) 3.4.1 (Mandrakelinux 10.1 3.4.1-4mdk)"
– 12 –
.note.GNU-stack,"",@progbits
אופרנדים
)(פרמטרים
של הפקודה
מהדרים
המהדר הוא תוכנית גדולה ומתוחכמת.
מקבל הרבה החלטות על איך לייצר קוד assemblyיעיל.
מכיל אופטימיזציות רבות לתיקון 'קוד גרוע' של מתכנתים.
חשוב להבין מה המהדר יכול לעשות ומה לא.
כך נוכל 'לעזור לו' לעזור לנו.
נוכל לייצר קוד יעיל יותר.
קיימים מספר קורסים בטכניון העוסקים בשלב זה.
"תורת הקומפילציה"
– – 13
דוגמה- אופטימיזציות של מהדרים
while (j < maximum - 1){
j = j + (4+array[k])*pi+5; }
( יכול להיעשות מחוץ4+array[k])*pi+5 ושלmaximum – 1 החישוב של
: התוצאה.ללולאה
int maxval = maximum - 1;
int calcval = (4+array[k])*pi+5;
while (j < maxval){
j = j + calcval; }
:ניתן אפילו
j = j + floor((maxval – j)/calcval) * calcval;
– 14 –
שלב Assembler :3
נותר לתרגם את hello.sלשפת מכונה
קרוב לייצוג בינארי של hello.s
יוצר קובץ בשם hello.o
לידיעה :קיימת אפשרות לתרגום בכיוון ההפוך.
תוכניות מסוג זה נקראות disassemblers
ב objdump –d <program name.o> :Linux
– – 15
שלב :4קישור )(linking
הקוד של printfנמצא בקובץ .oאחר המסופק עם הספריות
הסטנדרטיות של .C
המקשר ) (linkerמחבר את שני הקבצים ויוצר קובץ .hello
– – 16
חידה
מהי שפת התכנות הקטנה ביותר שנותנת פונקציונליות מלאה ?
שלושת הפקודות הבאות מספיקות:
השמה x := y
if
goto
מסקנה :בפועל כל המחשבים וכל השפות נותנים לנו בדיוק את אותה
פונקציונליות (יכולת חישובית).
(עד כדי אילוצי זיכרון שונים)
מהירות שונה
– – 17
ועכשיו -החומרה
בקורס זה נעסוק רק מעט בחומרה.
חשוב להבין רק את המבנה הכללי של המחשב.
ועכשיו ...נשימה עמוקה
– – 18
כתובת הפקודה
הבאה
CPU
כאן נעשים
החישובים
Register file
PC
Pentium - מבנה כללי
אחסון זמני
8 int, 8 float
ALU
System bus
Memory bus
Main
memory
I/O
bridge
Bus interface
I/O bus
USB
controller
Mouse Keyboard
– 19 –
Graphics
adapter
Display
זיכרון מבוסס על
מערך רכיבים
DRAM בשם
Disk
controller
– מוליךBUS
מידע בגודלDisk
32( ''מילה
)סיביות
Expansion slots for
other devices such
as network adapters
hello executable
stored on disk
מה המחשב עושה ?
שוב ושוב את אותו הדבר ("מחזור פקודה"):
קורא פקודה המוצבעת על ידי ה – PC
מפרש אותה
מבצע אותה
מעדכן את ה PCעם כתובת הפקודה הבאה.
לא סדרתי .למשל פקודת jmpמצביעה למקום קודם.
– – 20
סוגי פקודות ב assembler -
:Load העתק מילה מהזיכרון הראשי לרגיסטר.
:Store העתק מילה מרגיסטר לזיכרון.
:Update העתק תוכן של שני רגיסטרים ל ,ALUה ALUיבצע איתם חישוב
וישמור את התוצאה ברגיסטר.
:I/O read העתק מילה מהתקן I/Oלרגיסטר
להתקן I/O
ְ
:I/O write העתק מילה מרגיסטר
:Jump העתק את האופרנד לתוך ה PC
פקודות לוגיות ומתמטיותand,not,or,add, subt, mull, div :
– – 21
נחזור לתוכנית שלנו
הגיע הזמן לכתוב hello
– – 22
CPU
Register file
PC
ALU
System bus
Memory bus
Main "hello"
memory
I/O
bridge
Bus interface
I/O bus
USB
controller
Mouse Keyboard
User
types
"hello"
– 23 –
Graphics
adapter
Disk
controller
Expansion slots for
other devices such
as network adapters
Display
Disk
מגיע לזיכרוןhello
עכשיו מערכת ההפעלה נכנסת לפעולה
אחרי שהקשנו enterמערכת ההפעלה (אשר רצה ברקע כל הזמן)
מעלה את helloלזיכרון.
ב Unixזאת לא מערכת ההפעלה אלא shell
ההעלאה היא ישירה ,לא דרך המעבד
נקרא )Direct Memory Access (DMA
– – 24
CPU
Register file
PC
ALU
System bus
Memory bus
"hello,world\n"
Main
memory
hello code
I/O
bridge
Bus interface
I/O bus
USB
controller
Mouse Keyboard
Graphics
adapter
Disk
controller
Display
Disk
– 25 –
Expansion slots for
other devices such
as network adapters
hello executable
stored on disk
תמיד בזיכרון
0xffffffff
Kernel virtual memory
עכשיו התוכנית בזיכרון
Memory
invisible to
user code
User stack
(created at runtime)
Memory mapped region for
shared libraries
printf() function
תוכניות רבות
משתמשות בפונקציות
רק עותק אחד.ספריה
.בזיכרון
Run-time heap
(created at runtime by malloc)
Read/write data
Read-only code and data
– 26 –
0
Unused
קריאה לפונקציה
data + מוסיפה שורה
שהפונקציה שומרת
.כגון ערכי רגיסטרים
חזרה מפונקציה
מוחקת את המידע
.הזה
Loaded from the
hello executable file
עכשיו התוכנית בזיכרון
ה PCמצביע על הפקודה הראשונה.
בכל מחזור פקודה תתבצע פקודה אחת.
במקרה זה התוכנית גם תסתיים...
– – 27
CPU
Register file
PC
ALU
System bus
Memory bus
Main "hello,world\n"
memory
hello code
I/O
bridge
Bus interface
I/O bus
USB
controller
Mouse Keyboard
Graphics
adapter
Display
"hello,world\n"
– 28 –
Disk
controller
Disk
Expansion slots for
other devices such
as network adapters
hello executable
stored on disk