; *********************************************************************** ; * * ; * Compare Two Numbers (Fourth Version in Assembly Language) * ; * * ; *********************************************************************** ; Authors: Saeid Nooshabadi and John Zaitseff ; Date: 5th May, 2003 ; Version: 1.2 ; This program compares two integer numbers using a function, larger. The ; main point to note about this version is that it uses stack frames to ; preserve the value of certain registers. Doing so helps meet the ; requirements of the ARM Thumb Procedure Call Standard (ATPCS). ; ; Please note that this version uses an optimised version of the ATPCS. ; That Standard does NOT require a stack frame for every function, merely ; that the registers R4-R11 and R13 have the same value on exit as on ; entry; this program conforms to this standard. ; ; This program uses the ATPCS alias names for the registers. For example, ; A1-A4 are used instead of R0-R3. ; ----------------------------------------------------------------------- ; Assembly-language preamble for the main module .text ; Executable code follows _start: .global _start ; "_start" is required by the linker .global main ; "main" is our main program b main ; Start running the main program ; ----------------------------------------------------------------------- ; Function: main - Main program entry point ; Parameters: (none) - No parameters are passed ; Returns: int (in A1) - Return value: the value of "c" ; ; This function compares two integers stored in the variables "a" and "b". ; It uses the function "larger" to make the comparison. The larger of the ; two variables is stored in "c", which is returned to the operating ; system in register A1 (R0). ; ; This function conforms to the ATPCS; a full stack frame is generated ; using the "store multiple" and "load multiple" instructions. In ; general, the rule is either to generate no stack frame at all (see the ; function "larger" for an example) or to generate a full ATPCS stack ; frame. main: mov ip, sp ; Save the caller's stack pointer into IP stmfd sp!, {fp, ip, lr, pc} ; Save caller's FP, IP, LR and PC, ; modifying SP appropriately sub fp, ip, #4 ; Make FP point to one word (4 bytes) below the ; caller's SP (saved in IP). This marks the ; start of the stack frame (activation ; record) for the function main(). ldr a4, =a ; A4 = address of a ldr a1, [a4] ; A1 = 0xE0001234 ldr a2, [a4, #4] ; A2 = 0x00004567 (since A4+4 is address of b) bl larger ; Call "larger"; this automatically saves ; return address in LR (R14). Result ; returned in A1 (R0). ldr a4, =c ; A4 = address of c str a1, [a4] ; Store result (0x00004567) into c exit: ldmea fp, {fp, sp, pc} ; Use the frame pointer to restore the ; caller's FP, SP and PC. This returns ; to the caller. ; ----------------------------------------------------------------------- ; Function: int larger (int first, int second) ; ; This function compares "first" (in register A1, ie, R0) with "second" ; (in A2, ie, R1) and returns the larger of these in A1. Registers are ; preserved/destroyed according to the ATPCS. Only A1 is modified by this ; function. ; ; This comment illustrates an alternative way of documenting functions; ; compare this to the comments for main(), above. You may use whichever ; you prefer. ; ; This function does NOT generate a stack frame, since it is not strictly ; needed for the function to conform to the ATPCS. larger: cmp a1, a2 ; Compare "first" (A1) and "second" (A2) movle a1, a2 ; Place A2 in A1 if and only if A1 <= A2 ; Result is now in A1 (R0) mov pc, lr ; Return to the caller ; ----------------------------------------------------------------------- ; Program variables (stored together with the code) a: .word 0xE0001234 ; Variable "a" b: .word 0x00004567 ; Variable "b" c: .word 0 ; Variable "c" ; ----------------------------------------------------------------------- .end