Аритметичке и логичке операције Означени и неозначени бројеви Сабирање и одузимање Логичке операције Конструкција ALU Множење
Означени и неозначени бројеви Бројеви се представљају бинарно користећи двојични комплемент. Код MIPS-a бројеви су по правилу 32-битни и означени.
Означени и неозначени бројеви 32-битни означени бројеви: 0000 0000 0000 0000 0000 0000 0000 00002 = 010 0000 0000 0000 0000 0000 0000 0000 00012 = + 110 0000 0000 0000 0000 0000 0000 0000 00102 = + 210 ... 0111 1111 1111 1111 1111 1111 1111 11102 = + 2,147,483,64610 0111 1111 1111 1111 1111 1111 1111 11112 = + 2,147,483,64710 1000 0000 0000 0000 0000 0000 0000 00002 = – 2,147,483,64810 1000 0000 0000 0000 0000 0000 0000 00012 = – 2,147,483,64710 1000 0000 0000 0000 0000 0000 0000 00102 = – 2,147,483,64610 ... 1111 1111 1111 1111 1111 1111 1111 11012 = – 310 1111 1111 1111 1111 1111 1111 1111 11102 = – 210 1111 1111 1111 1111 1111 1111 1111 11112 = – 110 maxint minint
Означени и неозначени бројеви Садржај регистра или локације је низ битова који се може на различите начине интерперетирати. Бројеви могу да буду и неозначени, када сви битови представљају вредост броја. Код поређења вредности MIPS нуди инструкције које раде са означеним бројевима (slt, slti) али и са неозначеним (sltu, sltiu).
Означени и неозначени бројеви Пример Нека је у регистру $s0 бинарни број 1111 1111 1111 1111 1111 1111 1111 11112 а у регистру $s1 бинарни број 0000 0000 0000 0000 0000 0000 0000 00012. Које ће вредности бити у регистрима $t0 и $t1 после извршења следећих инструкција? slt $t0,$s0,$s1 #oznaceno poredjenje sltu $t1,$s0,$s1 #neoznaceno poredjenje
Означени и неозначени бројеви Одговор Вредност у регистру $s0 је -1, ако се ради о (означеном) целом броју, а 4,294,967,295, ако се ради о неозначеном целом броју. Вредност у регистру $s1 је у оба случаја 1. Према томе, регистар $t0 ће садржати 1 (-1<1) a $t1 ће садржати 0 (4,294,967,295 > 1).
Означени и неозначени бројеви У општем случају операнди не морају бити 32-битни. Поставља се питање како прелазимо са презентације неке вредности са n битова на презентацију те вредности са више од n битова? Ова операција назива се знаковно проширење и састоји се у копирању бита знака датог броја у све више битове.
Означени и неозначени бројеви Пример Конвертовати 16-битну бинар-ну вредност броја 2 у одгова-рајућу 32-битну вредност.
Означени и неозначени бројеви Одговор 16-битна вредност броја 2 је 0000 0000 0000 00102 = 210 32-битну вредност ћемо добити копирањем најстаријег бита броја (0) у леву половину чиме се добија 0000 0000 0000 0000 0000 0000 0000 00102 = 210
Означени и неозначени бројеви Исти поступак је и за негативне бројеве. Двојични комплемент 16-битне вредности броја 2 (или -2) добија се као 0000 0000 0000 00102 1111 1111 1111 11012 + 12 1111 1111 1111 11102 32-битна вредност је 1111 1111 1111 1111 1111 1111 1111 11102 = -210
Сабирање и одузимање Сабирање је једна од основних аритметичких операција коју подржавају сви рачунари. Одузимање се не врши директно већ се врши сабирање са двојичним комплементом умањиоца. Када резултат не може да се представи датим бројем битова (32 у овом случају) долази до прекорачења.
Сабирање и одузимање Прекорачење се не може јавити када сабирамо операнде различитог знака. Код одузимања се прекорачење не може јавити када одузимамо операнде истог знака, јер се то своди на сабирање операнда различитог знака. Како детектовати прекорачење у случајевима када је могућа његова појава?
Сабирање и одузимање Прекорачење се јавља када се пренос (позајмица) са бита десно од бита знака и пренос са бита знака не поклапају. Да ли операције са неозначеним бројевима могу да изазову прекорачење?
Сабирање и одузимање На пројектанту машине је да одлучи када ће се прекорачење игнорисати а када ће изазвати изузетак. MIPS препознаје два случаја: Инструкције add, addi и sub могу да изазову прекорачење. Код инструкција addu, addiu и subu прекорачење се игнорише.
Логичке операције Први рачунари су обраду вршили над речима. Убрзо је постало јасно да је добро имати могућност обраде поља битова или чак појединих битова унутар речи. Рад са знаковима унутар речи где је сваки од знакова 8-битан је један од примера за ово.
Логичке операције Једна од група оваквих операција су операције померања. Нека, на пример регистар $s0 садржи 0000 0000 0000 0000 0000 0000 0000 1101 После померања за 8 места улево његов садржај ће бити 0000 0000 0000 0000 0000 1101 0000 0000
sll $t2,$s0,8 # $t2 = $s8 << 8 Логичке операције Дуална операција операцији померања улево је операција померања удесно. MIPS инструкције које обављају ове операције су sll (shift left logical) и srl (shift right logical). sll $t2,$s0,8 # $t2 = $s8 << 8
Логичке операције Сада можемо да схvатимо значење поља shamt у R-формату. 0 0 16 10 8 0 op rs rt rd shamt funct
Логичке операције Такође су корисне операције И и ИЛИ (AND и OR) које се могу употребити за издвајање неког поља битова. Ове операције (and, andi, or, ori) обављају се над одговарајућим битовима изворних операнада, а резултат смешта у одговарајући бит одредишног операнда.
Логичке операције Ако је још увек у $t2 а у $t1 0000 0000 0000 0000 0000 1101 0000 0000 а у $t1 0000 0000 0000 0000 0011 1100 0000 0000 тада после извршења инструкције and $t0,$t1,$t2 #$t0 = $t1 & $t2 у регистру $t0 имамо садржај 0000 0000 0000 0000 0000 1100 0000 0000
Логичке операције Овакви шаблони битова називају се маске и помоћу њих неки битови могу да се обришу а неки да остану са оригиналном вредношћу. Слично томе, ИЛИ операцију можемо да користимо да поставимо неке од битова.
Логичке операције Ако су садржаји регистара $t1 и $t2 непромењени, онда операција or $t0,$t1,$t2 #$t0 = $t1 | $t2 даје следећи садржај регистра $t0: 0000 0000 0000 0000 0011 1101 0000 0000
Логичке операције Пример int data; Нека је дат следећи код на језику C struct { unsigned int ready: 1; unsigned int enable: 1; unsigned int receivedByte: 8; } receiver; … data = receiver.receivedByte; receiver.ready = 0; receiver.enable = 1; Написати одговарајући MIPS код ако су променљиве data и receiver додељене регистрима $s0 и $s1.
Логичке операције Одговор Језик C десно поравна ва поља па је изглед речи enable 31 … 10 9 2 1 0 ready receivedByte
Логичке операције Први корак је да изолујемо 8-битно поље receivedByte померајући га на лево а затим на десно sll $s0,$s1,22 srl $s0,$s0,24 док следеће две инструкције бришу бит најмање тежине, тј. постављају следећи бит andi $s1,$s1,0xfffe ori $s1,$s1,0x0002
Логичке операције Треба водити рачуна о томе да addi, addiu и slti, sltiu врше знаковно проширење својих непосредних операнада! Како andi и ori нормално раде са неозначеним операндима, њихови непосредни операнди се тако и третирају, тј. допуњују се нулама.
Конструкција ALU ALU извршава све аритметичке и логичке операције у рачунару. Због једноставности ћемо покушати да направимо 1-битну ALU. Пошто су речи код MIPS-a 32-битне, повезаћемо 32 такве ALU.
Конструкција ALU Користићемо већ познате “градивне блокове”. S A C B 1 Мултиплексер
Конструкција ALU Логичке операције су најлакше за имплементацију, јер већ имамо логичка кола која их реализују. Једнобитна ALU за операције AND и OR приказна је на слици. операција резултат 1 а b
Конструкција ALU Следећа фунцкија ALU је сабирање. cout = ab + acin + bcin sum = a xor b xor cin
Конструкција ALU 1-битна ALU која обавља функције AND, OR и сабирање.
Конструкција ALU 32-битна ALU која обавља функције AND, OR и сабирање. Сабирач који се добија директним повезивањем преноса 1-битних сабирача назива се ripple carry adder.
Конструкција ALU Одузимање је сабирање са двојичним комплементом умањиоца! a-b = a +b +1
Конструкција ALU Још увек нам треба подршка поређењу (инструкцији slt). slt има за резултат 1 ако је rs < rt, а иначе резултат је 0. a – b < 0 a < b Значи да slt поставља се битове на 0 осим бита најмање тежине који се поставља у зависности од резултата поређења.
Конструкција ALU
Конструкција ALU
Конструкција ALU
Конструкција ALU
Конструкција ALU Управљачке линије Функција 000 and 001 or 010 add 110 subtract 111 set on less then
Конструкција ALU a b ALU operation Zero ALU Result Overflow CarryOut 3 32 ALU operation Result a b ALU Overflow Zero CarryOut 3
Конструкција ALU RCA је исувише спор! Постоје многе шеме за предвиђање преноса код којих је потребно време log2n ако сабирају два n-тобитна броја. Једна таква шема је carry-lookahead сабирач (понекад се овај тип зове и carry-anticipation сабирач.
Конструкција ALU Размотримо један четворобитни паралелни сабирач (RCA). x y cout cin S S3 x3 y3 c3 S2 x2 y2 c2 S1 x1 y1 c1 S0 x0 y0 c0 x y
Конструкција ALU Начин генерисања преноса може се изразити као c0 = x0y0 (1) c1 = x1y1 + (x1 y1)c0 (2) Заменом (1) у (2) добијамо c1 = x1y1 + (x1 y1)x0y0 (3)
Конструкција ALU Слично је и c2 = x2y2 + (x2 y2)c1 (4) Заменом (3) у (4) добијамо c2 = x2y2 + (x2 y2)x1y1 + (x1 y1)x0y0 = x2y2 + (x2 y2)x1y1 + (x2 y2) (x1 y1)x0y0 (5)
Конструкција ALU Најзад c3 = x3y3 + (x3 y3)c2 (6) Заменом (5) у (6) добија се c3 = x3y3 + (x3 y3)x2y2 + (x2 y2)x1y1 + (x2 y2)(x1 y1)x0y0 = x3y3 + (x3 y3)x2y2 + (x3 y3)(x2 y2)x1y1 + (x3 y3)(x2 y2) (x1 y1)x0y0 (7)
Конструкција ALU Дефинишимо сигнале Pi (carry - propagate) и Gi (carry - generate) за i-ти степен сабирача као: Pi = xi yi (8) Gi = xiyi (9) Pi указује на то када се улазни пренос i–тог степена простире ка наредном a Gi указује да се на излазу i–тог степена генерише пренос независно од улазног преноса.
Конструкција ALU Заменом (8) и (9) у (1), (3), (5) и (7) добијамо c0 = G0 c1 = G1 + G0 P1 c2 = G2 + G1 P2 + G0 P2 P1 c3 = G3 + G2 P3 + G1 P3 P2 + G0 P3 P2 P1
Конструкција ALU Пренос ка наредном степену је ci+1 = xi yi + ci (xi + yi) = Gi + ci Pi (10) Заменом ci = Gi-1 + ci-1 Pi-1 у (10) добијамо ci+1 = Gi + Gi-1 Pi + ci-1 Pi-1 Pi (11) Настављајући даље рекурзивно добијамо ci+1 = Gi + Gi-1 Pi + Gi-2 Pi-1 Pi + ci-2 Pi-2 Pi-1 Pi = = . . . = = Gi + Gi-1 Pi + Gi-2 Pi-2 Pi + ... + c0 P0 P1 ... Pi (12)
Конструкција ALU cin = 0 FA x0 y0 S0 G0 P0 x1 y1 S1 G1 P1 x2 y2 S2 G2
Конструкција ALU Међутим, превише би било компликовано направити овакав 16-битни или 32-битни сабирач! Уместо тога се праве групе (од по 4) CLA које се повезују на RC начин или чак поново на CL начин.
Конструкција ALU
Множење Множење је знатно сложеније од сабирања. Састоји се од низа померања и сабирања. Захтева више времена и меморије од сабирања.
Множење Број битова производа је m+n, ако је n број битова множеника а m број битова множиоца. Обично множимо 32-битне бројеве и добијамо 32-битни производ па је могуће прекорачење!
Множење 1000 множеник (multiplicand) 1001 множилац (multiplier) 1000 0000 1001000 производ (product) Очигледно, ако је текућа цифра множиоца 1, треба ставити на одговарајуће место множеник, а када је 0 онда уписујемо нуле на одговарајуће место.
Множење Циљ нам је да хардвер који врши множење буде оптималан. Видећемо три верзије. За сада претпостављамо множење само ненегативих бројева.
Множење
Множење
Множење Како је око половине цифара множиоца једнако нули па се врши непотпуно сабирање са нулом, а 64-битна ALU спора и непотребна прешло се на нову идеју. Претходни алгоритам помера множеник улево при чему се убацују нуле са десне стране па множеник не утиче на LS цифру производа.
Множење Шта ако уместо померања множеника улево померамо производ удесно? Сада је множеник фиксиран у односу на производ а потребни сабирач само 32-битни.
Множење
Множење
Множење Следеће запажање је да је 64-битни регистар производа заправо улудо утрошен простор величине множиоца. Како битови производа “нестају” услед померања, тако нестају (бивају искоришћени) и битови множиоца.
Множење У трећој верзији у 64-битном регисту комбиновани су производ у вишем делу и множилац у нижем делу. Алгоритам почиње смештањем множиоца у десну половину и смештањем нула леву половину.
Множење
Множење
Множење До сада смо претпоставили множење позитивих бројева. Наједноставнији начин за множење означених бројева је да се и множеник и множилац претворе у позитивне бројеве памтећи оригиналне знаке. Алгоритам за множење треба да уради 31 итерацију остављајући битове знакова необухваћене израчунавањем, а производу треба променити знак уколико су оригинални знаци различити.
Множење Елегантнији приступ множењу означених бројева је Бутов (Booth) алгоритам. Овај алгоритам полази од запажања да, уз постојање могућности и сабирања и одузимања, постоји више начина да се израчуна производ.
Множење Ако множимо 2 и 6, тј. 00102 и 01102: 0010 0110 0110 + 0000 shift (0 у множиоцу) + 0010 add (1 у множиоцу) + 0010 add (1 у множиоцу) + 0000 shift (0 у множиоцу) 00001100
Множење Бут је приметио да ALU која може да сабира или одузима може да добије исти резултат на више начина. На пример, како је 6 = -2 + 8 или 0110 = -0010 + 1000 можемо да заменимо низ јединица у множиоцу једним одузимањем на почетку низа и сабирањем после последње јединице у низу.
Множење 0010 0110 + 0000 shift (0 у множиоцу) 0110 + 0000 shift (0 у множиоцу) - 0010 sub (прва 1 у множиоцу) + 0000 shift (унутар низа 1) + 0010 shift (0 у множиоцу) 00001100
Множење Бутов алгоритам треба брже да се извршава обзиром да је у то време померање било брже од сабирања. Алгоритам функционише и за означене бројеве. Кључна карактеристика овог алгоритма је да класификује групе битова на оне у почетку, у средини и на крају низа јединица. 0 1 1 1 1 0 Почетак поворке Средина поворке Крај поворке
Множење Почетни подниз састављен од нула не изазива никакву аритметичку операцију. Ако посматрамо само по 2 суседна бита можемо закључити о којем случају се ради. Текући бит Бит с десна Објашњење Пример 1 Почетак поворке јединица 00001111000 Средина поворке јединица Крај поворке једниница Средина поворке нула
Множење Бутов алгоритам се од већ изложеног алгоритма множења разликује у томе што се уместо једног бита множиоца посматрају по 2 бита. Наредни корак је померање производа удесно.
Множење Алгоритам сада гласи: У зависности од текућег и претходног бита обавља се следеће: 00: усред низа нула нема аритметичких операција. 01: крај низа јединица, додаје се множеник левој половини производа. 10: почетак низа јединица, одузима се множеник од леве половине производа. 11: усред низа јединица, нема аритметичких операција. 2. Као и раније померање регистра производа за један бит удесно.
Множење Итерација Множеник Оригинални алгоритам Бутов алгоритам Корак Производ 0010 Почетно 0000 0110 0000 0110 0 1 1: 0 no oper. 1a:00no oper. 2: shift right pr. 0000 0011 0000 0011 0 2 1a:1 pr=pr+mcand 0010 0011 1c:10pr=pr-mcand 1110 0011 0 0001 0001 1111 0001 1 3 0011 0001 1d:11 no oper 0001 1000 1111 1000 1 4 1:0 no operation 1b:01 pr=pr+mcand 0001 1000 1 0000 1100 0000 1100 0 Крајњи десни бит код Бутовог алгоритма је десни сусед текућег бита пре померања; на почетку узимамо да је његова вредност 0. Да би очували знак производа вршимо аритметичко померање удесно.
Множење Пример Испробајмо Бутов алгоритам на множењу негативних бројева. Нека је у питању 2 -3 = -6 или 0010 1101 = 1111 1010
Множење Итерација Корак Множеник Производ Почетне вредности 0010 Почетне вредности 0010 0000 1101 0 1 1c:10 Prod=Prod-Mcand 1110 1101 0 2: shift right Prod 1111 0110 1 2 1b:10 Prod=Prod+Mcand 0001 0110 1 0000 1011 0 3 1110 1011 0 1111 0101 1 4 1d:11 no operation 1111 1010 1
Множење Множење основом еквивалентно је померању улево! Можемо показати да Бутов алгоритам заиста коректно ради за означене бројеве. Нека је a множилац а b множеник, при чему ai означава бит i од a.
Множење Ако преформулишемо Бутов алгоритам у смислу битова множиоца онда важи следећа табела. ai ai-1 Операција Не ради ништа 1 Сабери b Одузми b
Множење Уместо у табеларном облику алгоритам можемо представити изразом (ai-1 – ai) где вредност овог узраза представља следеће акције 0: не ради ништа +1: додај b -1: одузми b
Множење Како се померање множеника улево у односу на регистар производа може сматрати множењем основом (2), Бутов алгоритам се може написати као збир (а-1 – а0) b 20 + (а0 – а1) b 21 + (а1 – а2) b 22 … … + (а29 – а30) b 230 + (а30 – а31) b 231
Множење Ову суму можемо поједноставити ако приметимо да је -аi 2i + аi 2i+1 = (-аi + 2аi)2i = аi2i не заборављајући да је а-1=0 и извлачећи b из сваког сабирка b((а31 -231) + (а30 -230) + … + (а1 -21) + (а0 -20)) Израз у загради је двојични комплемент од а па је коначни резултат bа
Множење MIPS пружа могућност да два регистра садрже 64-битни производ (Hi и Lo). Две инструкције за множење mult и multu (неозначени) а за добијање 32-битног производа користи се mflo (move from lo). Игнорише се прекорачење ако производ не може да стане у 32 бита.