Presentation is loading. Please wait.

Presentation is loading. Please wait.

Компьютерийн зохион байгуулалт, ассемблер CS201

Similar presentations


Presentation on theme: "Компьютерийн зохион байгуулалт, ассемблер CS201"— Presentation transcript:

1 Компьютерийн зохион байгуулалт, ассемблер CS201
Лекц – 12 Стек \STACK С.Байгалтөгс. ШУТИС-КТМС 2009/Хавар [

2 MIPS Регистрүүд. [

3

4 Стек \STACK [

5 Стек \STACK Энэ сэдвээр стек болон стекийн заагч регистр $sp-н тухай үзнэ. Бүлгийн сэдвүүд: Стек Стекийн заагч регистр $sp Стекийн Push ба Pop үйлдлүүд. MIPS стек. Стекийн хөрвүүлэлтийн хэрэглээ. Жишээ тэмдэгт мөрийн урвуу хэлбэр. Анхааруулга: Энэ бүлэг дэх жишээ програмууд нь , SPIM симуляторийн псевдокомандууд нь ON , delayed branches нь OFF, мөн delayed loading нь OFF юм. [

6 Стек Стек нь санах ойд өгөгдөл зохион байгуулах аргачлал юм. Стек дэх өгөгдлүүдийн харагдац нь өрсөн тавагнууд шиг харагддаг байна. Өгөгдлүүдийг стек бүтцэд нэмэх эсвэл хасах нь өрсөн таваг нэмэх эсвэл эсвэл хасах аналог замаар явагддаг. Энгийн үед стекийн бүх үйлдэл оройн хэсэгт (top) хийгдэнэ. Хэрэв таваг нэмэх хэрэгтэй бол тавгаа стекийн оройд байрлуулна. [

7 Урвуу(Upside-down) MIPS Стек
Стек маягын үйл явцыг заримдаа "LIFO" буюу Last In First Out гэж нэрлэдэг. Манай хичээлийн стек дэх өгөгдлийн элементүүд 32-бит үг (word) урттай. Ерөнхийдөө стекийг өгөгдлийн бүх төрөлд ашиглах боломжтой. Харин энэ сэдэвт стек нь зөвхөн 32-бит MIPS үг (word) агуулах юм. Зурган дээр MIPS-ийн үг агуулсан стекийг үзүүлэв. Стекийн заагч регистр (Stack point register) болох $sp нь стекийн оройн хэсгийг заана. Стек заагч нь регистр $29 юм. Мнемоник регистр нэр $sp нь өргөтгөсөн ассемблерт ашиглагдана. Хэвийн тохиолдолд стек санах ойг зурахдаа урвуу хэлбэртэй зурдаг. Зурган дээр стекийн оройн хэсэг нь 81 болох юм. Стекийн доод хэсэг нь -92 гэсэн бүхэл тоон утгыг агуулжээ. Үйлдлийн систем эхлэхээс өмнө програм стект тохирсон санах ойн хязгаар бий эсэхийг баталгаажуулж тохирох хаягыг  $sp-д өгнө. [

8 Урвуу (Upside-down) MIPS Стек
[

9 Push Програм хангамжийн хувьд $sp нь үргэлж стекийн оройн хэсгийг заана. Түүнчлэн стек нь доош буурах замаар өсдөг (Санах ойн хаягын зарчимаар). Иймд манай 4-байтын (full word) өгөгдөлтэй стекийн хувьд өгөгдөл нэмэхдээ $sp-ээс 4-ийг хасаж тухайн хаягт өгөгдлийг хадгална. Энэ үйлдлийг push гэж нэрлэнэ. Өгөгдлийг стек рүү push хийхэд эхэлж стек заагчийн утгаас 4-ийг хасаж дараа нь стек заагчийн хаягт түүнийг хадгалдаг. Код дээр хэрхэн харагдахыг үзүүлэв. Стект оруулах утга нь регистр $t0-д хадгалагдаж байна: # Өгөгдлийг PUSH the item in $t0: subu $sp,$sp, # шинэ өгөгдлийн байрлалыг заана, sw $t0,($sp) # $t0-н агуулгыг тухайн шинэ байрлал болгон хадгална [

10 Push [

11 Pop Стекээс өгөгдлийг гаргах үйлдлийг pop гэж нэрлэдэг. Програм хангамжийн хувьд стекээс өгөгдлийг “гаргах” үйлдэл гэдэг нь өгөгдлийг өөр байрлал руу хуулах ба стек заагч нь дахин тохируулагддаг гэж ойлгогдож болох юм. Зурган дээр pop үйлдлийг үзүүлжээ. Эхлээд өгөгдөл стекийн оройн хэсгээс шинэ байрлал руу хуулагдаж дараа нь стекийн заагч нь 4-өөр нэмэгдэнэ. Стекийн оройн элементийг pop хийхэд стек заагчийн зааж байгаа элементийг хуулсаны дараа стек заагчийн утга дээр 4- ийг нэмэх юм. Код дээр хэрхэн бичигдсэнийг үзүүлэв. Утгыг $t0 руу гаргая гэж санавал: # $t0 руу элементийг гаргах: lw $t0,($sp) # Элементийг $t0 руу хуулна. addu $sp,$sp,4 # Хуучин оройн хэсгийн доор байрлах элементийг заана. [

12 Pop [

13 Жишээ програм Регистрүүд ашиглагдаж байх үед стекийг ихэвчлэн өгөгдлийн утгыг түр зуур хадгалах зориулалтаар ашигладаг. Үүний жишээ нь стек ашиглан хөрвүүлэгч хэрхэн арифметик илэрхийллийг машин код руу хөрвүүлэхийг үзье Арифметик илэрхийлэл нь ab - 12a + 18b – 7 ба зөвхөн регистр $t0 ба $t1-г ашиглах боломжтой. SPIM нь програмыг ажиллуулж эхлэхээс өмнө стек заагч $sp-ийн утгыг зөв тодорхойлно. Бүхий л компьютер дээр стек заагчийн утгыг хэрэглэгчийн програм эхлэхээс өмнө үйлдлийн системээр тодорхойлогддог. Жишээ програм: [

14 Жишээ програм # ab - 12a + 18b - 7 main: lw $t0,a # get a
lw $t1,bb # get b mul $t0,$t0,$t1 # a*b subu $sp,$sp,_____ # push a*b onto stack sw $t0,______ .data a: 2 bb: 3 [

15 Програмын үргэлжлэл Илэрхийллийн элементүүдийг стек рүү орууллаа (push). Дараа нь нийлбэрийн утга -7 гэж тавигдах ба элементүүдийг стекээс гаргаж (pop) нийлбэр дээр нэмнэ. [

16 Програмын үргэлжлэл # ab - 12a + 18b - 7 .globl main lw $t0,a # get a
lw $t1,bb # get b mul $t0,$t0,$t # a*b subu $sp,$sp, # push a*b onto stack sw $t0,($sp) lw $t0,a # get a li $t1, # mul $t0,$t0,$t # -12a subu $sp,$sp, # push -12a onto stack lw $t0,bb # get b li $t1, # mul $t0,$t0,$t # 18b subu $sp,$sp, # push 18b onto stack li $t1, # init sum to -7 lw $t0,_____ # pop 18b addu $sp,$sp,______ addu $t1,$t1,$t # 18b [

17 Бүрэн програм Хэрэв их хэмжээний регистрүүд боломжтой байсан бол илэрхийллийг стект биш регистрүүдэд хадгалаад явах боломжтой юм. Гэхдээ том хэмжээтэй програмд олон регистрүүд ашигласан ч яг энэ зарчмаар үйлдлүүд хийгдэнэ. Програмын бүтэн хувилбарыг үзүүлэв: [

18 Бүрэн програм # ab - 12a + 18b - 7
# Settings: Load delays OFF; Branch delays OFF, # Trap file ON; Pseudoinstructions ON .globl main main: lw $t0,a # get a lw $t1,bb # get b mul $t0,$t0,$t1 # a*b subu $sp,$sp,4 # push a*b onto stack sw $t0,($sp) lw $t0,a # get a li $t1, # mul $t0,$t0,$t1 # -12a subu $sp,$sp,4 # push -12a onto stack [

19 Бүрэн програм lw $t0,bb # get b li $t1,18 # mul $t0,$t0,$t1 # 18b
subu $sp,$sp, # push 18b onto stack sw $t0,($sp) li $t1, # init sum to -7 lw $t0,($sp) # pop 18b addu $sp,$sp,4 addu $t1,$t1,$t0 # 18b -7 lw $t0,($sp) # pop -12a addu $t1,$t1,$t0 # -12a + 18b -7 lw $t0,($sp) # pop ab addu $t1,$t1,$t0 # ab - 12a + 18b -7 done: li $v0, # print sum move $a0,$t # syscall li $v0, # exit syscall .data a: word 0 bb: .word 10 [

20 Runtime Stack Хамгийн сайн компьютерийн системд ч хязгаарлагдмал санах ойн орон зай байдаг. Иймээс програм анх ачаалагдахад үйлдлийн систем нь их хэмжээний стек зай өгдөг. Зурган дээр үйлдлийн систем хэрхэн програмыг эхлэхэд санах ойг хэрхэн хуваарилж байгаа үзүүлжээ. 4Гбайтын боломжит санах ой байна. Санах ойн хэсэг нь 0x ээс 0x7FFFFFFF хүртэлх зайнд өгөгдлийн сегмент болон стек сегментэд зай гаргаж өгчээ. Энэ нь 1.8 Гигабайт зай. [

21 Runtime Stack [

22 Runtime Stack Програм эхлэхдээ санах ойн заагчийн ($sp) утгыг 0x7FFFEFFC (хэрэглэгчийн санах ойн оройн хэсгийн доор байрлах үг (full word)-ийн хаяг) болгоно. Програм ажиллахад стек нь боломжит зай хүртэл доош чиглэж өснө. Харин өгөгдлийн сегмент нь дээш чиглэж өснө. Мэдээж динамик програмд сегментийг өсөж бас агшдаг. Хэрэв сегментүүдийн нэгдсэн зай нь боломжит зайнаас хэтэрвэл тэдгээрийн зааг нь хязгаарын дунд хэсгийн хаа нэгтэй тааралдана. Ингэвэл санах ой үлдээгүй гэсэн үг юм. Санах ой зохицуулах арга нь 0x ээс 0x7FFFFFFF хоорондох зайн хагасыг стект, хагасыг нь өгөгдөлд хуваарилах явдал юм. [

23 Урвуу Тэмдэгт мөр Заншил ёсоор бол машин командын сегментийг “text” нэрлэдэг. Сегмент ажиллаж эхлэх үед “process” гэж нэрлэгдэнэ. Энд стекийн хэрэглээний сонгодог жишээг үзүүлэв. Хэрэглэгч тэмдэгт мөр оруулах ба програм үүнийг нь урвуу болгон гаралт руу бичнэ. Програмын хэрхэн ажиллаж байгааг ойлгохын тулд дараах диаграмыг үзүүлжээ. Тэмдэгт мөр "Hello“-г тэмдэгт тэмдэгтээр нь стек рүү push хийв. Дараа нь тэмдэгтүүд стекээс буцаж эх тэмдэгт мөр рүүгээ pop хийгдэнэ. Стек руу оруулсан сүүлийн тэмдэгт эхэнд стекээс гарна. Энэ үйлдэл нь тэмдэгтүүдийн байрыг сольж урвуу болгох юм. [

24 Урвуу Тэмдэгт мөр Стек дэх тэмдэгт бүр үгний (full word) доод эрэмбийн байтад хадгалагдах 2 байт хэмжээтэй юм. [

25 Дүгнэлт Програмын дүгнэлт. Тайлбарууд нь програмын гол хэсгийг илэрхийлнэ. .text .globl main main: # input the string # push each character onto the stack # pop chars from stack back into the buffer # print the reversed string .data str: .space # character buffer [

26 Эхний хэсэг Програмын эхний хэсэг нь терминалаас нэг мөр уншина.
Програмын эхний хэсэг нь терминалаас нэг мөр уншина. Дараа нь, стекийн утгыг тохируулна. Null утгыг стек руу оруулна(push). Үүний дараа, энэ null хүртэлх утгуудыг гаргана (pop). [

27 Эхний хэсэг # Reverse and output a user-supplied string
# Settings: Load delays OFF; Branch delays OFF, # Trap file ON; Pseudoinstructions ON # $t0 --- character pushed or popped # $t1 --- index into string buffer str .text .globl main main: # input the string li $v0, # service code la $a0,str # address of buffer li $a1, # buffer length syscall # initialize the stack: li $t0,_____ # push a null ____ $sp,$sp,4 # onto the stack sw $t0,(___) # to signal its bottom li $t1, # index of first char in str buffer [

28 Эхний хэсэг # push each character onto the stack
# pop chars from stack back into the buffer # print the reversed string .data str: .space # character buffer [

29 Тэмдэгтүүдийг оруулах (pushing)
Дараагийн алхам нь, тэмдэгтийн буфер дэх тэмдэгтүүдийг стек рүү нэг нэгээр нь оруулах юм. Эхний командыг тэмдэгтийг буферээс $t0-н байт руу ачаалахад ашиглана. Дараа нь, ачаалсан тэмдэгтийг шалгана.Хэрэв энэ нь null (тэмдэгт) бол давталтаас гадуур салаалалтыг удирдана. Үгүй бол тэмдэгтийг стек руу оруулна (push). Гэх мэтээр энэ процесс давтагдана. [

30 Тэмдэгтүүдийг оруулах (pushing)
# Reverse and output a user-supplied string # Settings: Load delays OFF; Branch delays OFF, # Trap file ON; Pseudoinstructions ON # $t0 --- character pushed or popped # $t1 --- index into string buffer str .text .globl main main: # input the string li $v0, # service code la $a0,str # address of buffer li $a1, # buffer length syscall li $t0, # push a null subu $sp,$sp,4 # onto the stack sw $t0,($sp) # to signal its bottom li $t1, # index of first char in str buffer [

31 Тэмдэгтүүдийг оруулах (pushing)
# push each character onto the stack pushl: lbu $t0,str($t1) # get current char into # a full word ____ $t0,stend # null byte: end of string subu $sp,$sp, # push the full word ___ $t0,($sp) # holding the char addu $t1, # inc the index j _____ # loop stend: # pop chars from stack back into the buffer # print the reversed string .data str: .space # character buffer [

32 Тэмдэгтүүдийг гаргах (popping)
Тэмдэгт мөр дэх Null байт тааралдвал эхний давталт төгсөж дараагийн давталт эхлэнэ. Энэ дараагийн давталт нь стекийн доод хэсэгт байрлах null тэмдэгт дайралдах хүртэл тэмдэгтүүдийг стекээс гаргах юм. Стекээс гарах тэмдэгт бүр буферт хадгалагдах хуучин тэмдэгтүүдийг дарж хуулагдана. Тэмдэгт мөрийн төгсгөлд байрлах null тэмдэгт дарж хуулагдахгүй. [

33 Тэмдэгтүүдийг гаргах (popping)
# push each character onto the stack pushl: lbu $t0,str($t1) # get current char into # a full word beqz $t0,stend # null byte: end of string subu $sp,$sp, # push the full word sw $t0,($sp) # holding the char addu $t1, # inc the index j pushl # loop # pop chars from stack back into the buffer stend: li $t1, # index of first byte of str buffer popl: ____ $t0,($sp) # pop a char off the stack ____ $sp,$sp,4 beqz $t0,done # null means empty stack ____ $t0,str($t1) # store at string[$t1] j popl # loop # print the reversed string .data str: .space # character buffer [

34 Сүүлчийн шат Програмын сүүлчийн шатанд тэмдэгтэн үр дүнг дэлгэцэнд хэвлэнэ. [

35 Сүүлчийн шат . . . . . # pop chars from stack back into the buffer
stend: li $t1, # index of first byte of str buffer popl: lw $t0,($sp) # pop a char off the stack addu $sp,$sp,4 beqz $t0,done # null means empty stack sb $t0,str($t1) # store at string[$t1] addu $t1, # inc the index j popl # loop # print the reversed string done: li $v0, # service code la $a1,str # address of string syscall li $v0, # exit syscall .data str: .space # character buffer [

36 Бүлгийн төгсгөл Бүлэгт үзсэн сэдвүүд Стекийн талаарх ойлголт.
LIFO бүтэц. Стек заагч ба урвуу MIPS стек. Push Pop Run-time stack MIPS санах ойн text сегментүүд. [


Download ppt "Компьютерийн зохион байгуулалт, ассемблер CS201"

Similar presentations


Ads by Google