INF2270 L?sningsforslag oppgave uke 15 (9.-14.4.2008) Oppgave 1a void rlcopy (char *to, char *from) { while (*from) { if (isdigit(*from)) { int n = *from-'0', i, c = *(from+1); from += 2; for (i = 0; i < n; ++i) *(to++) = c; } else { *(to++) = *(from++); } } *to = 0; } Oppgave 1b .globl rlcopy # Navn: rlcopy # Synopsis: Kopiering med ekspansjon av run-length-koding # C-signatur: void rlcopy (char *to, char *from) # Registre: AL - arbeidsregister # CL - teller (ved ekspansjon) # DL - tegnet som ekspanderes # EDI - to (?kes etterhvert) # ESI - from (?kes etterhvert) rlcopy: pushl %ebp # Standard movl %esp,%ebp # funksjonsstart. pushl %esi # Gjem ogs? ESI pushl %edi # og EDI. movl 12(%ebp),%esi # Initi?r ESI movl 8(%ebp),%edi # og EDI. rlc_l: cmpb $0,(%esi) # Kommer vi til 0-byten, jz rlc_done # er vi ferdige. cmpb $'0',(%esi) # Hvis neste tegn jb rlc_cp # ikke er et siffer cmpb $'9',(%esi) # (dvs '0'-'9'), ja rlc_cp # s? hopp til rlc_cp. # Ekspandering movb (%esi),%cl # Hent antallet. subb $'0',%cl # Konvert?r til verdi. movb 1(%esi),%dl # Hent ogs? tegnet som skal kopieres. addl $2,%esi # rlc_exp: cmpb $0,%cl # S? lenge CL > 0: jle rlc_l # movb %dl,(%edi) # Kopi?r tegnet. incl %edi # Oppdat?r pekeren og decb %cl # telleren. jmp rlc_exp # G? i l?kke. # Kopiering rlc_cp: movb (%esi),%al # Hent neste tegn movb %al,(%edi) # og flytt det. incl %esi # Oppdat?r incl %edi # pekerne. jmp rlc_l # Gjenta hovedl?kken. # Ferdig rlc_done: movb $0,(%edi) # Husk 0-byten! popl %edi # Hent tilbake EDI, popl %esi # ESI og popl %ebp # EBP. ret # Retur.