Програмски језик ниског нивоа

Из Википедије, слободне енциклопедије

Програмски језик ниског нивоа је програмски језик који пружа мало или нимало апстракције у односу на скуп инструкција архитектуре рачунара. Генерално се ово односи на машински или асемблерски код. Реч „ниског“ се односи на скоро непостојећу апстракцију између језика и машинског језика; и због тога, често се за језике ниског нивоа каже да су „близу хардвера“.

Језици ниског нивоа се могу конвертовати у машински код без коришћења компајлера или преводиоца, и резултујући код се директно извршава на процесору. Програм написан у језику ниског нивоа се може направити тако да се јако брзо извршава, и са веома малим меморијским заузећем; еквивалентан програм написан у језику високог нивоа је захтевнији. Језици ниског нивоа су једноставни, али се сматра да су тешки за коришћење, због разних техничких детаља које треба памтити.

Ради поређења, програмски језик вишег нивоа одваја семантику извршења архитектуре рачунара од спецификације програма, што поједностављује развој софтвера.

Програмски језици ниског нивоа се могу поделити у две категорије : прва генерација, и друга генерација.

Машински код[уреди]

Машински код је једини језик који микропроцесор може да директно изврши (процесира) без претходне трансформације. Тренутно, програмери готово никада не пишу програме директно у машинском коду, јер захтева обраћање пажње на бројне детаље које би језик високог нивоа аутоматски обрадио, и такође захтева да се напамет знају или често проверавају нумерички кодови за сваку инструкцију која се користи. Из овог разлога, програмски језици друге генерације пружају један ниво апстракције на машинском коду.

Пример: функција у 32-битном x86 машинском коду за рачунање н-тог Фибоначијевог броја:

8B542408 83FA0077 06B80000 0000C383
FA027706 B8010000 00C353BB 01000000
B9010000 008D0419 83FA0376 078BD98B
C84AEBF1 5BC3

Асемблер[уреди]

За асемблерски језик се каже да је језик ниског нивоа зато што, иако није матерњи језик микропроцесора, програмер асемблерског језика и даље мора да разуме јединствену архитектуру микропроцесора (нпр. његове регистре и инструкције). Ове једноставне инструкције се онда директно уграђују у машински код. Асемблерски код може такође да се апстрахује на још један слој на сличан начин као што се машински код апстрахује у асемблерски код.

Пример: Исти Фибоначијев број се рачуна као у претходном примеру, али у x86 асемблерском језику користећи синтаксу Мајкрософт макро асемблера:

fib:
    mov edx, [esp+8]
    cmp edx, 0
    ja @f
    mov eax, 0
    ret
    
    @@:
    cmp edx, 2
    ja @f
    mov eax, 1
    ret
    
    @@:
    push ebx
    mov ebx, 1
    mov ecx, 1
    
    @@:
        lea eax, [ebx+ecx]
        cmp edx, 3
        jbe @f
        mov ebx, ecx
        mov ecx, eax
        dec edx
    jmp @b
    
    @@:
    pop ebx
    ret

Програмирање ниског нивоа у језицима високог нивоа[уреди]

Експерименти са хардверском подршком у језицима високог нивоа у касним 1960-им годинама довела су до тога да језике попут ПЛ/С, БЛИС, БЦПЛ, и проширен АЛГОЛ за Буроусове велике системе се користе за програмирање ниског нивоа. Форт такође има употребу као системски језик. Међутим, језик који је постао доминантан у системском програмирању је Ц.

За Ц се сматра да је програмски језик треће генерације, јер је структуриран и апстрахује машински код. Међутим, велики број данашњих програмера би могли рећи да је Ц ниског нивоа, јер му фали велики број функција које су данас стандард (нема сакупљача ђубрета итд.), практично подржава само скаларне операције, и пружа директно меморијско адресирање. С тога, оно се лепо уклапа са асемблерским језиком и машинским нивоом процесора и микроконтролера. Способност Ц-а да апстрахује од машинског нивоа значи да исти код може бити компајлиран за различите хардверске платформе; међутим, прецизна контрола на системском нивоу је и даље могућа под условом да жељена платформа има одређене спецификације, нпр. линеарни меморијски модул, и меморија подељена на бајтове. Програми у Ц-у могу захтевати одређену количину „дотеривања“, често имплементирано условним компајлирањем, за различите жељене платформе. Процес адаптације системског програма за различиту платформу је познато као портовање.

Пример: функција која рачуна н-ти Фибоначијев број у Ц-у:

unsigned int fib(unsigned int n)
{
    if (n <= 0)
        return 0;
    else if (n <= 2)
        return 1;
    else {
        int a,b,c;
        a = 1;
        b = 1;
        while (1) {
            c = a + b;
            if (n <= 3) return c;
            a = b;
            b = c;
            n--;
        }
    }
}

Спољашње везе[уреди]