Computer Systems Org I - Prof. Grishman

Lecture 23 - Nov. 24, 2004

Putting C and LC-3 together:  generating code for functions with pointers (cont'd)

We now consider some C functions for strings, and how they translate into LC-3 code.

strlen (string length) -- version 1

    int a;
    main () {
       a = strlen("moo");
    }
    int strlen (char* s) {
       int ctr = 0;
       while (*s) { s++; ctr++;}
       return ctr;
    }


In LC-3 assembler:

         .ORIG x3000
main     LEA   R1,moo           ; a = strlen("moo")
         JSR   strlen
         ST    R0, a
         HALT
         ; function strlen (char* s)
         ;                        R1 = s [passed as parameter]
         ;                        R0 = ctr [return value]
strlen   AND   R0, R0, 0        ; ctr = 0
loop     LDR   R2, R1, 0        ; R2 = *s
         BRZ   done             ; if (*s == 0) quit loop
         ADD   R1, R1, 1        ; s++
         ADD   R0, R0, 1        ; ctr++
         BR    loop
done     RET                    ; return ctr
moo      .STRINGZ "moo"         ; static constants and variables
a        .FILL 0
         .END

strlen (string length) -- version 2

    int a;
    main () {
       a = strlen("moo");
    }
    int strlen (char* s) {
       char* p = s;
       while (*s) s++;
       return s - p;
    }


In LC-3 assembler:

         .ORIG x3000
main     LEA   R1,moo           ; a = strlen("moo")
         JSR   strlen
         ST    R0, a
         HALT
         ; function strlen (char* s)
         ;                        R1 = s [passed as parameter]
         ;                        R2 = p
strlen   ADD   R2, R1, 0        ; p = s
loop     LDR   R3, R1, 0        ; R3 = *s
         BRZ   done             ; if (*s == 0) quit loop
         ADD   R1, R1, 1        ; s++
         BR    loop
done     NOT   R2, R2           ; R2 = -p
         ADD   R2, R2, 1
         ADD   R0, R1, R2       ; R0 = s - p
         RET                    ; return s - p
moo      .STRINGZ "moo"         ; static constants and variables
a        .FILL 0
         .END

This loop requires 4 instructions / character;  we can reduce it to 3 instructions / character by moving the conditional branch to the end of the loop, so there is only one branch per loop:

strlen   ADD   R2, R1, 0        ; p = s
         LDR   R1, R1, 0        ; R3 = *s [first character]
         BRZ   done             ; if (first character == 0) return
loop     ADD   R1, R1, 1        ; s++
        
LDR   R1, R1, 0        ; R3 = *s [next character]
         BRNP  loop             ; if (next character != 0) loop
done     ... as before ...

strcpy (string copy)

    char stg[5];
    main () {
       strcpy (stg, "moo");
    }
    void strcpy
(char* d, char* s) {
       while (*d = *s) { s++; d++; ]
    }


in LC-3 assembler:

         .ORIG x3000
main     LEA   R1, stg          ; strcpy (str, "moo")
         LEA   R2, moo
         JSR   strcpy
         HALT
         ; function strcpy (
char* d, char* s)
         ;                        on entry
         ;                        R1 = d
         ;                        R2 = s
strcpy   LDR   R3, R2, 0        ; R3 = *s
         STR   R3, R1, 0        ; *d = *s
         BRZ   done             ; if ((*d = *s) == 0) quit loop
         ADD   R2, R2, 1        ; s++
         ADD   R1, R1, 1        ; d++
         BR    strcpy           ; loop
done     RET
moo      .STRINGZ "moo"         ; static constants and variables
stg      .FILL 0
         .FILL 0
         .FILL 0
         .FILL 0
         .FILL 0
         .END