INF2270 Oppgaver uke 11 (9.-13.3.2009) (Om du ikke har tid til ? gj?re alle oppgavene denne uken, er oppgave 3 og 4 de viktigste.) Oppgave 1 Skriv C-funksjonen void strrev (char *s) som snur rekkef?lgen p? tegnene i `s?. Eksempel: #include #include extern void strrev (char *s); int main (void) { char txt[100]; strcpy(txt, "Abc..0123456789"); strrev(txt); printf("Teksten er n? \"%s\".\n", txt); return 0; } vil skrive ut: Teksten er n? "9876543210..cbA". Hint: Bruk to pekere som starter i hver sin ende av teksten og g?r mot hverandre. Da kan man la de to tegnene pekerne peker p? bytte plass. Oppgave 2 Skriv funksjonen fra forrige oppgave i x86-assemblerkode. Oppgave 3 Skriv funksjonen int summany (int a, ...) som summerer alle parametrene; funsjonen skal skrives i x86-assemblerkode. Det kan v?re vilk?rlig mange parametre (dvs minst ¨Śn) og en parameter 0 er alltid siste parameter (og den naturligivs eneste 0 i parameterlisten). Eksempel: #include extern int summany (int a, ...); /* Ja, dette er lovlig C! */ int main (void) { int sum = summany(1, 2, 3, 99, -100, 0); printf("Summen er %d\n", sum); } skal skrive ut: Summen er 5 Hint: Her trenger du en peker som kan g? gjennom stakken. Den brukes til ? summere tallene den peker p? inntil den finner verdien 0. Oppgave 4 P? lysark 6 i forelesningen 9.3 ble det vist en funksjon 'arrayadd'. Her er den sammen med et testprogram: .globl arrayadd # Navn: arrayadd. # Synopsis: Summerer verdiene i en vektor. # C-signatur: int arrayadd (int n, int a[]). # Registre: %eax: summen s? langt # %ecx: indeks til a (teller ned) # %edx: adressen til a arrayadd: pushl %ebp # Standard movl %esp,%ebp # funksjonsstart. movl $0,%eax # sum = 0. movl 8(%ebp),%ecx # ix = n. movl 12(%ebp),%edx # a. a_loop: decl %ecx # while (--ix js a_exit # >=0) { addl (%edx,%ecx,4),%eax # sum += a[ix]. jmp a_loop # } a_exit: popl %ebp # return sum. ret # #include extern int arrayadd (int a[], int n); int a[] = { 100, 1, 2, 3, 4, 5, 6}; int main (void) { int a_len = (sizeof(a)/sizeof(int)), i; for (i = 0; i <= a_len; ++i) printf("n=%d: sum=%d\n", i, arrayadd(a,i)); return 0; } N? er det imidlertid lagt inn en feil i enten funksjonen eller testprogrammet slik at en kj?ring gir ?Segmentation fault?. Bruk feils?kingsverkt?y til ? finne feilen. Hint: Kildekoden til funksjonen og testprogrammet kan hentes fra ~inf2270/programmer/aa.s og ~inf2270/programmer/test-aa.c. Oppgave 5 X86-instruksjonen loop dit gj?r f?lgende: 1. Register ECX telles ned med 1. 2. Hvis ECX ikke er 0, hoppes til `dit?. Bruk denne instruksjonen til ? gj?re funksjonen `arrayadd? (se lysark 6 fra forelesningen 10.3) kortere. Det er for eksempel mulig ? skrive l?kken med bare to instruksjoner. Oppgave 6 (Ukens n?tt) Skriv en funksjon int littleendian (void) som returnerer ?sann? (dvs en annen verdi enn 0) om maskinen benytter ?little-endian? lagring. Funksjonen kan skrives i C eller x86-kode.