diff options
Diffstat (limited to 'asmcall.s')
-rw-r--r-- | asmcall.s | 63 |
1 files changed, 63 insertions, 0 deletions
diff --git a/asmcall.s b/asmcall.s new file mode 100644 index 0000000..1523187 --- /dev/null +++ b/asmcall.s @@ -0,0 +1,63 @@ +; This source code in this file is licensed to You by Castle Technology +; Limited ("Castle") and its licensors on contractual terms and conditions +; ("Licence") which entitle you freely to modify and/or to distribute this +; source code subject to Your compliance with the terms of the Licence. +; +; This source code has been made available to You without any warranties +; whatsoever. Consequently, Your use, modification and distribution of this +; source code is entirely at Your own risk and neither Castle, its licensors +; nor any other person who has contributed to this source code shall be +; liable to You for any loss or damage which You may suffer as a result of +; Your use, modification or distribution of this source code. +; +; Full details of Your rights and obligations are set out in the Licence. +; You should have received a copy of the Licence with this source code file. +; If You have not received a copy, the text of the Licence is available +; online at www.castle-technology.co.uk/riscosbaselicence.htm +; +; > s.asmcall RCC 24-Mar-88 +; +; This makes it possible to call code which scribbles on all the +; registers with a standard ARM procedure call, e.g. from C. +; +; If the code called also scribbles on lk, you must regain control +; by forcing it to branch to asmcall_exit. +; +; NB it relies on scribbling on memory addressed pc-relative, so it +; won't work if the code area is not writable. +; + +r0 RN 0 +r1 RN 1 +r2 RN 2 +r3 RN 3 +r4 RN 4 +ip RN 12 +lk RN 14 +pc RN 15 + + AREA |C$$code|, CODE, READONLY + EXPORT asmcall_call + EXPORT asmcall_exit + +asmcall_savedregs + DCD 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; 11 words for registers +asmcall_call + ; Enter with r0: thing to call + ; r1, r2, r3: parameters for it + + ADR ip, asmcall_savedregs + STMIA ip, {r4-lk} + MOV ip, r0 + MOV r0, r1 + MOV r1, r2 + MOV r2, r3 + MOV lk, pc + MOV pc, ip +asmcall_exit + NOP ; 2 spurious instructions here in case the caller + NOP ; forgets to allow for prefetch ... + ADR ip, asmcall_savedregs + LDMIA ip, {r4-lk} + MOV pc, lk + END |