We can always re-write a for-statement into an equivalent program using a while-statement as follows:
for ( expr1; condition; expr2 ) <==> expr1; statements while ( condition ) { statements; expr2; } |
We already discussed how to convert a while-construct in assembler code....
int A[10]; int sum, i; sum = 0; for (i = 0; i < 10; i++); sum = sum + A[i]; |
We first convert the for-loop into an equivalent while-loop:
int A[10]; int sum, i; sum = 0; i = 0; while ( i < 10 ) { sum = sum + A[i]; i = i + 1; } |
The flow chart of the above program is:
An ARM assembler program that implement the above loop construct is:
main: // sum = 0; - always execute the RHS first !!! mov r0, #0 // r0 = 0 - ready to save it movw r1, #:lower16:sum movt r1, #:upper16:sum // r1 = addr(sum) str r0, [r1] // sum = 0; // i = 0; mov r0, #0 // r0 = 0 - ready to save it // (not necessary, because r0 is already = 0...) movw r1, #:lower16:i movt r1, #:upper16:i // r1 = addr(i) str r0, [r1] // i = 0; while: // START of while loop // Test while condition i < 10 movw r0, #:lower16:i movt r0, #:upper16:i // r0 = addr(i) ldr r1, [r0] // r1 = i; cmp r1, #10 // Check: i < 10 bge whileEnd // If i >= 10: exit while loop /* *********************************** While body *********************************** */ // sum = sum + A[i] //// Get sum movw r0, #:lower16:sum movt r0, #:upper16:sum // r0 = addr(sum) ldr r2, [r0] // r2 = sum; //// Get A[i] (use base + offset access technique !) movw r0, #:lower16:A movt r0, #:upper16:A // r0 = addr(sum) --- Base address movw r1, #:lower16:i movt r1, #:upper16:i // r1 = addr(i) ldr r1, [r1] // r1 = i --- index add r1, r1, r1 // r1 = 2*i add r1, r1, r1 // r1 = 4*i --- Offset ! ldr r3, [r0,r1] // r3 = A[i] //// compute sum + A[i] add r2, r2, r3 // r2 = sum + A[i] //// Store result in sum (in memory) movw r0, #:lower16:sum movt r0, #:upper16:sum // r0 = addr(sum) str r2, [r0] // sum = sum + A[i] // i = i + 1 movw r0, #:lower16:i movt r0, #:upper16:i // r0 = addr(i) ldr r2, [r0] // r2 = i; add r2, r2, #1 // r2 = i + 1 str r2, [r0] // i = i + 1; // End of while body --- branch back to test !! b while whileEnd: /* -------------------------------------------------- Begin of the permanent program variables -------------------------------------------------- */ .data A: .4byte 4, 6, 7, 3, 8, 2, 9, 1, 5, 10 // int array (with 10 values) sum: .skip 4 i: .skip 4 .end |
How to run the program:
|
int A[10]; int max, i; max = A[0]; for ( i = 1; i < 10; i++ ) { if ( A[i] > max ) max = A[i]; } |
Convert to while loop:
int A[10]; int max, i; max = A[0]; i = 1; while ( i < 10 ) { if ( A[i] > max ) max = A[i]; i++; } |
The flow chart of the above program is:
ARM assembler program that implements (= realizes) this program control flow:
main: // max = A[0]; - always execute the RHS first !!! movw r0, #:lower16:A movt r0, #:upper16:A // r0 = addr(A) = addr(A[0]) ldr r0, [r0] // r0 = A[0]; - ready to save it movw r1, #:lower16:max movt r1, #:upper16:max // r1 = addr(max) str r0, [r1] // max = 0; // i = 1; mov r0, #1 // r0 = 1 - ready to save it movw r1, #:lower16:i movt r1, #:upper16:i // r1 = addr(i) str r0, [r1] // i = 1; while: // START of while loop // Test while condition i < 10 movw r0, #:lower16:i movt r0, #:upper16:i // r0 = addr(i) ldr r1, [r0] // r1 = i; cmp r1, #10 // Check: i < 10 bge whileEnd // If i >= 10: exit while loop /* *********************************** While body *********************************** */ // if ( A[i] > max ) //// Get A[i] (use base + offset access technique !) movw r0, #:lower16:A movt r0, #:upper16:A // r0 = addr(sum) --- Base address movw r1, #:lower16:i movt r1, #:upper16:i // r1 = addr(i) ldr r1, [r1] // r1 = i --- index add r1, r1, r1 // r1 = 2*i add r1, r1, r1 // r1 = 4*i --- Offset ! ldr r2, [r0,r1] // r2 = A[i] //// Get max movw r0, #:lower16:max movt r0, #:upper16:max // r0 = addr(max) ldr r3, [r0] // r3 = max; //// Compare A[i] (= r2) < max (= r3) cmp r2, r3 ble ifEnd /* ******************************** Then-part: max = A[i] Note: r0 = addr(max), r2 = A[i] ******************************** */ str r2, [r0] // max = A[i] ifEnd: // i = i + 1 movw r0, #:lower16:i movt r0, #:upper16:i // r0 = addr(i) ldr r2, [r0] // r2 = i; add r2, r2, #1 // r2 = i + 1 str r2, [r0] // i = i + 1; // End of while body --- branch back to test !! b while whileEnd: /* -------------------------------------------------- Begin of the permanent program variables -------------------------------------------------- */ .data A: .4byte 4, 6, 7, -3, 8, 2, -9, 1, 5, -10 max: .skip 4 i: .skip 4 .end |
How to run the program:
|