;TIEA325 ;Jani Kurhinen ;2.4.2008 ;cacl.asm ; ;Vastaa seuraavanlaista C-kielistä koodia ; ;#include ;int calc(int i, int j, int k) ;{ return (i+j)*k;} ; ;int main(void) ;{ ; int a=1; ; int b=2; ; int c=3; ; int d; ; d=calc(a,b,c); ; printf("Tulos on %d\n",d); ; return 0; ;} ; ;Käännä jalavassa komennolla ;nasm -f elf calc.asm ;ja linkitä gcc:n avustuksella ;gcc -m32 -o calc calc.o ; ;ebp on ohjelmalohkon pinomuistialueen alkuosoitin ;esp on pino-osoitin ;*push ja pop-käskyt muokkaavat esp:tä, mutta sitä voi myös itse käpistellä ;*HUOM! x86:ssa pino kasvaa "alaspäin" ;eax on akkurekisteri, johon aritmeettiset operaatiot tallentavat tuloksensa. ;Myös aliohjelmat palauttavat arvonsa akussa. ; extern printf;Myös assemblerissa voidaan käyttää ulkoisia funtioita. ;Tämä vastaa C-kielen funktion esittelyä. SECTION .data print_string: db "Tulos on %d",10,0 ;Merkkijono, rivinvaihto ja loppunolla. SECTION .text calc: ;Hyppyviite eli label push ebp ;Vanha basepointteri talteen pinoon mov ebp,esp ;basepoitterille uusi arvo nykyisen pinon päältä mov eax,[ebp+8];1.parametri add eax,[ebp+12];2.parametri imul eax,[ebp+16];3.parametri mov esp,ebp ;Palautetaan stackpoitteri samaan arvoon kuin tullessa. pop ebp ;Palautetaan basepoitteri (stackpointer muuttuu myös) ret ;Palataan kutsupaikkaan. global main ;main komponentin entrypointti. main: ;Tässä on main-label, ei siis tuo ylempi direktiivi. push ebp ;Vanha basepointteri talteen pinoon mov ebp,esp ;basepoitterille uusi arvo nykyisen pinon päältä sub esp,16 ;Varataan tilaa neljälle dword muuttujalle (integer) ;Tilaa on siis [ebp] -- [ebp-16] mov dword [ebp-4],1 ;Sijoitetaan arvot muuttujille a mov dword [ebp-8],2 ;b ja mov dword [ebp-12],3;c push dword [ebp-12] ;Valmistaudutaan aliohjelmakutsuun push dword [ebp-8] ;viemällä parametrit pinoon. push dword [ebp-4] ;Huomaa järjestys! call calc ;Aliohjelmakutsu add esp,12 ;Stackpointteri 3 dwordiä taaksepäin mov [ebp-16],eax ;Neljäs (d) muuttuja paikoillensa pinoon push eax ;Parametrit pinoon aliohjelmakutsua varten. push dword print_string call printf add esp,8; ;Paramertien poisto pinosta aliohjelman jälkeen mov esp,ebp ;Palautetaan stackpoitteri ja pop ebp ;basepointteri alkuperäisiin arvoihin mov eax,0 ;Lopetetaan ohjelma nollalla ret ;