.global main, Stop, CodeEnd, DataStart, DataEnd .global head, searchKey, searchValue main: /* ---------------------------------------------- searchValue = Lookup(head, searchKey) We must pass parameter on the stack because Lookup is not a leaf subroutine ----------------------------------------------- */ // Pass searchKey using the stack movw r0, #:lower16:searchKey movt r0, #:upper16:searchKey // r0 = addr(searchKey) ldr r0, [r0] // r0 = searchKey push {r0} // Pass searchKey on the stack // Pass head using the stack movw r0, #:lower16:head movt r0, #:upper16:head // r0 = addr(head) ldr r0, [r0] // r0 = head push {r0} // Pass head on the stack // Call Lookup( ) bl Lookup add sp, sp, #8 // Clean up parameters // Return value is in r0 // Store result in "searchValue" movw r1, #:lower16:searchValue movt r1, #:upper16:searchValue // r0 = addr(searchValue) str r0, [r1] Stop: nop /* ============================================================= Lookup(h, searchKey) int Lookup( List h, int searchKey ) { if ( h == null ) return 0; // Not found is represented by 0 else if ( h.key == searchKey ) return (h.value); else return Lookup( h.next, searchKey ); } Stack frame structure for Lookup( ) is: FP----> +-----------+ | old FP | +-----------+ | ret addr | +-----------+ FP+8 | h | +-----------+ FP+12 | searchKey | +-----------+ ============================================================= */ Lookup: /* ================================== Prelude: build stack frame ================================== */ push {lr} push {fp} mov fp, sp sub sp, sp, #0 // 0 local variables // if ( h == null ) ldr r0, [fp,#8] // r0 = h cmp r0, #0 bne else1 // return(0) in r0 mov r0, #0 /* ===================================================== Postlude: de-allocate locals, restore FP and return ===================================================== */ mov sp, fp pop {fp} pop {pc} else1: // if ( h.key == searchKey ) ldr r0, [fp,#8] // r0 = h ldr r0, [r0,#0] // r0 = h.key ldr r1, [fp,#12] // r1 = searchKey cmp r0, r1 bne else2 // return (h.value); in register r0 !!! ldr r0, [fp,#8] // r0 = h ldr r0, [r0,#4] // r0 = h.value /* ===================================================== Postlude: de-allocate locals, restore FP and return ===================================================== */ mov sp, fp pop {fp} pop {pc} else2: // Call Lookup( h.next, searchKey ) ldr r0, [fp,#12] // r0 = searchKey push {r0} // Pass searchKey as parameter on stack ldr r0, [fp,#8] // r0 = h ldr r0, [r0,#8] // r0 = h.next push {r0} // Pass h.next as parameter on stack // Call Lookup( ) with parameters: h.next and searchKey on stack bl Lookup add sp, sp, #8 // Clean up parameters // It just happens that Lookup( ) return its value in r0 // So we don't need to do anything // return (Lookup( )'s return value ); already in register r0 !!! /* ===================================================== Postlude: de-allocate locals, restore FP and return ===================================================== */ mov sp, fp pop {fp} pop {pc} /* --------------------------- END Lookup ----------------------------- */ CodeEnd: nop /* ************************************************************** Permanent variables ************************************************************** */ .data DataStart: searchKey: .4byte 333 searchValue: .4byte 0 head: .4byte p0 // head contains the address of the first list elem // head->[111,58]->[222,67]->[333,34]->[444,87]->[555,98] // list structure is: [int value, next] p0: .4byte 111,58,p3 // p0 contains [111, 58, p3] p1: .4byte 333,34,p2 // p1 contains [333, 34, p2] p2: .4byte 444,87,p4 // p2 contains [444, 87, p4] p3: .4byte 222,67,p1 // p3 contains [222, 67, p1] p4: .4byte 555,98,0 // p4 contains [555, 98, 0] DataEnd: .end