INF2270 L?sningsforslag oppgaver uke 12 (16.-20.3.2009) Oppgave 1 char *mystrcpy (char *to, char *from) { char *tx = to, *fx = from; while (*fx != 0) { *tx = *fx; ++tx; ++fx; } *tx = 0; return to; } .globl mystrcpy # Navn: mystrcpy # Synopsis: Kopierer en tekst. # C-signatur: char *strcpy (char *to, char *from). # Registre: AL - tegnet som kopieres # CX - der neste tegn skal hentes fra (vil ?ke) # DX - der neste tegn skal plasseres (vil ?ke) mystrcpy: pushl %ebp # Standard movl %esp,%ebp # funksjonsstart. movl 8(%ebp),%edx # Initi¨¦r EDX movl 12(%ebp),%ecx # og ECX. m_loop: movb (%ecx),%al # Hent neste tegn movb %al,(%edx) # og flytt det. cmpb $0,%al # Hvis tegner var 0, je m_exit # er vi ferdig. incl %ecx # ?k ECX incl %edx # og EDX og jmp m_loop # gjenta det hele. m_exit: movl 8(%ebp),%eax # Hent returvedien: to. popl %ebp # Standard ret # retur. Oppgave 2 void rlcopy (char *to, char *from) { while (*from) { if (isdigit(*from)) { int n = *from-'0', i, c = *(from+1); for (i = 1; i <= n; ++i) *(to++) = c; from += 2; } else { *(to++) = *(from++); } } *to = 0; } .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. Oppgave 3 # EAX = a EDX = b xorl %eax,%edx # EAX = a EDX = b^a = a^b xorl %edx,%eax # EAX = a^(a^b) = b EDX = a^b xorl %eax,%edx # EAX = b EDX = (a^b)^b = a Husk: ^ er XOR (i C-notasjon).