INF2270 L?sningsforslag oppgaver uke 11 (12.-16.3.2007) Oppgave 1 .text .globl yellower # Navn: yellower. # Synopsis: Gj?r en farge mer gul. # Signatur i C: struct color { # unsigned char r, g, b; # }; # void yellower (struct color *c). # Registre: AX - en farge i c. # BX - en farge i gul. # EDX - teller # EDI - c # ESI - &yellow. yellower: pushl %ebp # Standard movl %esp,%ebp # funksjonsstart. pushl %ebx # EBX, pushl %esi # ESI og pushl %edi # EDI er ?callee save?. movl 8(%ebp),%esi # Initi?r ESI, leal yellow,%edi # og EDI. movl $2,%edx # EDX = 2. # do { y_loop: movb (%esi,%edx,1),%al # AX = c.r; andw $0x00FF,%ax # (unsigned short) movb (%edi,%edx,1),%bl # BX = yellow.r; andw $0x00FF,%bx # (unsigned short) addw %bx,%ax # ((AX+BX) shrw $1,%ax # /2); movb %al,(%esi,%edx,1) # c.r = (unsigned char) decl %edx # } while (--EDX jns y_loop # >= 0). popl %edi # Hent tilbake EDI, popl %esi # ESI og popl %ebx # EBX. popl %ebp # Standard ret # retur. .data # struct color yellow = { yellow: .byte 251 # 251, .byte 248 # 248, .byte 0 # 0 } ; .align 2 Oppgave 1b Alle `and?-instruksjonene kan droppes. Da skjer f?lgende: %ax: xxxxxxxx vvvvvvvv %bx: xxxxxxxx vvvvvvvv der x er ukjent bit og v data. Etter addisjonen har vi %ax: xxxxxxxv vvvvvvvv og `shift?-operasjonen gir oss %ax: 0xxxxxxx vvvvvvvv som er riktig svar. Oppgave 2 # include extern int endian (void); int main (void) { if (endian()) printf("Maskinen er little-endian.\n"); else printf("Maskinen er big-endian.\n"); return 0; } .globl endian # Navn: endian # Synopsis: Er maskinen little-endian? # C-signatur: int endian (void) endian: pushl %ebp # Standard movl %esp,%ebp # funksjonsstart. movl $0,%eax # Hent 1. byte i `one? movb one,%al # utvidet til long. popl %ebp # ret # Retur. .data one: .long 1 Oppgaven kan alternativt besvares i ren C: #include int v1 = 1; int main (void) { if (*(char*)&v1) printf("Little-endian\n"); else printf("Big-endian\n"); return 0; } Her ?jukser? vi litt ved ? typekonvertere en int-peker til ? bli en char-peker. Da kan vi se p? bare den byte-en den peker p?. Enda finnes mange andre m?ter ? l?se oppgaven p?. Oppgave 3 Spesielt ? merke seg: * N?r vi skal kalle `mystrlen', m? vi legge parameteren p? stakken. Ved retur, m? vi fjerne den igjen. .globl mystrcat # Navn: mystrcat. # Synopsis: Utvider en tekst med en annen. # C-signatur: char *mystrcat (char *a, char *b). # Registre: %eax - g?r gjennom tegnene i a # %ecx - g?r gjennom tegnene i b # %edx - tegnene som flyttes mystrcat: pushl %ebp # Standard movl %esp,%ebp # funksjonsstart. movl 8(%ebp),%ecx # a pushl %ecx # ( ). call mystrlen # mystrlen popl %ecx # /* Rydd opp etter kallet. */ addl 8(%ebp),%eax # a += movl 12(%ebp),%ecx # /* Hent b. */ cat_loop: # do { movb (%ecx),%dl # c = *b . incl %ecx # ++ movb %dl,(%eax) # *a = c. incl %eax # ++ cmpb $0,%dl # } while (c jne cat_loop # != 0). cat_exit: movl 8(%ebp),%eax # return ?original a?. popl %ebp # Standard ret # retur. Oppgave 4 .globl innsist # Navn: innsist. # Synopsis: Setter inn sist i listen. # Signatur i C: void innsist (struct min_liste *p). # Registre: EAX - tempor?rregister # EDX - p innsist:pushl %ebp # Standard movl %esp,%ebp # funksjonsstart. movl 8(%ebp),%edx # Hent p. leal hode,%ecx # px = &hode. inn_l: cmpl $0,0(%ecx) # while (*px jz inn_s # ) { movl 0(%ecx),%ecx # px = *px. jmp inn_l # } inn_s: movl %edx,0(%ecx) # *px = p. movl $0,0(%edx) # *p = 0. popl %ebp # Retur. ret #