Planen for idag Datalogi 1F Forår 2003 G1 Et gensyn med KFirst G1 Jørgen Sværke Hansen cyller@diku.dk 2 Sidst så vi hvordan man starter den første proces KCurProc = KWaitQ.Get(); KFirst(KCurProc->sp); hvor KFirst er defineret ved: KFirst: ldgp gp, (pv) ldq pv, 0xD8(a0) // Pop pv addq a0, 0xF0,a0 // Skip registre bis a0, 0, sp // Sæt sp jmp (pv) // Hop til processtart Indhold af G1 3 små opgaver: 1. Oversæt en kerne og afvikl den på en kernealpha 2. Håndoversæt en C/C++ funktion til alpha assembler 3. Implementer procedurer til dynamisk lagerallokering og anvend dem (inkl. aflusning) i en eksisterende kerne 3 4 udviklings nettet Kernealphaerne udviklings Ethernet HUB DIKU s net Linux PC sniffer udviklings kerne Konsolboks kerne Ethernet HUB kerne 5 Udviklingsalpha erne: toke vile ve bure borr Prøv: ng2h del1-alpha erne Kernealpha erne archimedes diophant eudoxos euklid hypatia ptolemaios pythagoras thales zenon 6 1
7 8 9 10 Opgave 1 Hent d-kernen, oversæt den og kør den på en kerne-alpha: d-kernen findes i ~dat1f/kb4/kerner Kursusbog bind 5: Afsnit 3.5 beskriver hvordan man generelt oversætter, overfører og udfører et program på en kerne-alpha Afsnit 3.6 beskriver hvordan man oversætter, overfører og udfører en af kursusbog-kernerne på en kerne-alpha 11 12 2
Opgave 2 Håndoversættelse af en C/C++ funktion til alphaassembler Funktionen beregner udtryk der er specificeret via binære træer 12 3 13 x x + 11 5 Knuderne i træet Hver knude har formen: typedef struct node { int value; struct node *left; struct node *right; exprnode; Hvis knuden er en intern knude (dvs. hvis (left!= NULL) && (right!= NULL) angiver value en operation: 1 angiver addition 2 angiver multiplikation Hvis knuden er en bladknude, angive value en heltallig værdi 14 Beregningsfunktionen int calc(exprnode *root) { int rval, lval; if(root == NULL) return 0; if((root->left == NULL)&&(root->right == NULL)) return root->value; else { lval = calc(root->left); rval = calc(root->right); switch(root->value) { case ADDOP: return lval+rval; case MULOP: return lval*rval; default: return 0; 15 Testeksempler I ~dat1f/g1/trees.h er der angivet en række testtræer: // Tree 0: result 42 exprnode t0_n1_1 = {42, NULL, NULL; exprnode *t0_root = &t0_n1_1; samt definitionen af exprnode 16 - assembler Beskrives i kursusbog bind 5: Kapitel 4: Programmering i assembler Funktionsdefinition i assembler.ent calc.globl calc calc: ldgp gp, (pv) <gem udvalg af registre på stakken> <programkode for calc> <reetabler registre fra stakken> ret (ra).end calc 17 18 3
Funktionskald i alpha-assembler <gem udvalgte registre på stak> <initialiser argumentregistre> lda pv, calc jsr ra, (pv) ldgp gp, (ra) <processering af returværdi (v0)> <retabler udvalgte registre fra stak> 19 Register $0 $1-$8 $9-$15 $16-$21 $22-$25 $26 $27 $28 $29 $30 $31 Registrene på en Navn v0 t0-t7 s0-s6 a0-a5 t8-t11 ra pv at gp sp zero Funktion Returværdi Temp. registre Mellemregn. overlever funktionsk. Funktionsargumenter Mellemregninger Returadresse Addr. på kaldte procedure Reserveret assembler Global peger Stak peger Er altid nul Hvem gemmer kaldte kaldte Kaldte 20 Opgave 3 Bibliotek til dynamisk lagerallokering To funktioner: void *malloc(size_t size): allokerer en klods lager af størrelsen size på hoben void free(void *p): frigiver den klods lager, som p peger på Diverse G1 skal afleveres onsdag 26. februar klokken 14:00 i DIKUs førstedelsadministration Sammen med G1 har I fået fra Kernighan & Ritchie: The C Programming Language (2nd edition) fået udleveret: Kapitel 5: Pointers and Arrays Kapitel 6: Structures Appendiks B: Standard Library 21 22 Lagerallokering: malloc/free eksempel int main (void) { exprnode *enode; enode = (exprnode *) malloc(sizeof(exprnode)); enode->value = 54; enode->left = NULL; enode->right = NULL; printf( %d\n, calc(enode)); Lagerallokering: new/delete eksempel int main (void) { exprnode *enode; enode = new exprnode; // ingen typecast/size_of enode->value = 54; enode->left = NULL; enode->right = NULL; printf( %d\n, calc(enode)); free(enode); delete enode; 23 24 4
Allokering af hukommelse Funktioners lokale variable allokeres typisk på stakken Dynamisk allokerede variable allokeres på hoben HOB KODE STAK 25 Allokering af objekter på hoben: simpel algoritme Hoben består af en samling klodser af data, der enten: er allokerede (dvs. optaget) er frie (ikke optaget) Ved et kald til malloc skal der findes en fri blok, der har mindst samme størrelse som den forespurgte (og helst samme størrelse). Ved et kald til free markeres blokken som værende fri. 26 Eksempel på administration af hob p = malloc(0x007.fff0); p2 = malloc(0x007.fff0); free(p); free(p2); 0x040.0000 0x038.0000 0x036.0000 0x038.0000 0x000.0000 Ledig: Nej Ja 0x000.0000 0x036.0000 Ledig: Nej Ja 0x000.0000 Ledig: Ja Kommentarer til implementation I kan antage at argumentet til free altid har en korrekt værdi (men ellers kan de klares med f.eks. et magisk tal) Algoritmen lider af intern fragmentering: I er velkomne til f.eks. at sammenlægge blokke, men det er ikke et krav I kan IKKE flytte rundt på allokerede blokke! 27 28 Udførsel på kernealphaerne Programmer på kernealphaerne har kun de funktioner til rådighed, der er implementeret i den benyttede kerne: intet standardbibliotek eller køretidsbibliotek er tilgængeligt for jeres kode der er f.eks. ikke indbyggede standard funktioner for new og delete destruktøren for en klasse kalder en funktion builtin_delete, der ikke er defineret konstruktører og destruktører kaldes ikke automatisk for statisk allokerede klasser 29 Aflusning Til aflusning af kode på udviklingsalphaerne: gdb Til aflusning af kode på kernealpha erne: ladebug (fjerndebugger med kildetekstsupport der styres fra en udviklingsalpha) debug monitor på alphaerne Lav først en version, der virker på udviklingsalpha erne (se evt. testprogram.cc for at se hvordan det kan gøres) 30 5
Referencer i C++ void g() { int s = 0; int& sr = s; sr += 5; // sr = 5 efter dette int *ps = &s; *ps += 5; // s == sr == *ps == 10 ps += 5; // addr ps forhøjes med // 5*4 bytes 31 void inc(int& val) { val++; Mere reference main() { val = 1; inc(val); //val == 2 void inc(int* val) { (*val)++; main() { val = 1; inc(&val); //val == 2 32 Brug nyhedsgruppen diku.dat1f hvis I har problemer eller spørgsmål Vi ses næste gang den 28. februar!! 33 6