22fibonacci-2.pdf
TRANSCRIPT
-
8/14/2019 22Fibonacci-2.pdf
1/5
C Calling Convention
; main code
; ---------
; Pushes 5 onto the stack and calls Fib. Note that the 5 is never
; popped off the stack, even though it seems like it should be.
; The reason for this is that the unlk comes right after the jump
; to Fib and the compiler realized that unlinking clears the stack
; anyway.
00000000: 4E56 0000 link a6,#0
00000004: 4878 0005 pea 0x00000005
00000008: 4EB9 0000 0000 jsr Fib
0000000E: 4E5E unlk a6
00000010: 4E75 rts
; Fib code
; --------
; This version of Fib first sets up the stack and loads the; parameter (n) into D3 for quick and easy access. It then
; handles the base case. If the base case doesnt apply,
; the code calls Fib(n-2) and stores the result into a temporary
; local variable (-4 off A6). Finally, the code makes the Fib(n-1)
; call, adds the results, and returns.
;
; This function is not completely optimized, as it was automatically
; generated. However, it does show the calling conventions.
;
; Note: to save stack cleaning, this function doesnt clean off the
; stack until the end of the routine, when it adds 8 to the stack
; pointer.
00000000: 4E56 FFFC link a6,#-4
00000004: 2F03 move.l d3,-(a7)
00000006: 262E 0008 move.l 8(a6),d3
0000000A: 7002 moveq #2,d0
0000000C: B680 cmp.l d0,d3
0000000E: 6E04 bgt.s *+6 ; 0x00000014
00000010: 7001 moveq #1,d0
00000012: 601E bra.s *+32 ; 0x00000032
00000014: 2003 move.l d3,d0
00000016: 5580 subq.l #2,d0
00000018: 2F00 move.l d0,-(a7)
0000001A: 4EAD 0000 jsr Fib0000001E: 2D40 FFFC move.l d0,-4(a6)
00000022: 2003 move.l d3,d0
00000024: 5380 subq.l #1,d0
00000026: 2F00 move.l d0,-(a7)
00000028: 4EAD 0000 jsr Fib
0000002C: D0AE FFFC add.l -4(a6),d0
00000030: 504F addq.w #8,a7
00000032: 261F move.l (a7)+,d3
00000034: 4E5E unlk a6
00000036: 4E75 rts
-
8/14/2019 22Fibonacci-2.pdf
2/5
Pascal Calling Convention
; main code
; ---------
; This code works much like the main code with the C calling
; convention. The main difference is that the return value must
; be retrieved from the stack.
00000000: 4E56 0000 link a6,#0
00000004: 594F subq.w #4,a7
00000006: 4878 0005 pea 0x00000005
0000000A: 4EB9 0000 0000 jsr FIB
00000010: 201F move.l (a7)+,d0
00000012: 4E5E unlk a6
00000014: 4E75 rts
; Fib code
; --------
; The Fib code works much like the Fib code with the C calling; convention. One difference is that memory must be accessed and
; allocated for return values.
00000000: 4E56 FFFC link a6,#-4
00000004: 2F03 move.l d3,-(a7)
00000006: 262E 0008 move.l 8(a6),d3
0000000A: 7002 moveq #2,d0
0000000C: B680 cmp.l d0,d3
0000000E: 6E0A bgt.s *+12 ; 0x0000001a
00000010: 2F7C 0000 0001 move.l #1,20(a7)
0014
00000018: 6028 bra.s *+42 ; 0x00000042
0000001A: 594F subq.w #4,a7
0000001C: 2003 move.l d3,d0
0000001E: 5580 subq.l #2,d0
00000020: 2F00 move.l d0,-(a7)
00000022: 4EAD 0000 jsr FIB
00000026: 201F move.l (a7)+,d0
00000028: 2D40 FFFC move.l d0,-4(a6)
0000002C: 594F subq.w #4,a7
0000002E: 2003 move.l d3,d0
00000030: 5380 subq.l #1,d0
00000032: 2F00 move.l d0,-(a7)
00000034: 4EAD 0000 jsr FIB
00000038: 201F move.l (a7)+,d00000003A: D0AE FFFC add.l -4(a6),d0
0000003E: 2F40 0014 move.l d0,20(a7)
00000042: 261F move.l (a7)+,d3
00000044: 4E5E unlk a6
00000046: 4E74 0004 rtd #0x4
-
8/14/2019 22Fibonacci-2.pdf
3/5
C Calling Convention (A6 frames disabled)
; main code
; ---------
; Similar to the other main codes, but no LINK.
00000000: 4878 0005 pea 0x0000000500000004: 61FF 0000 0000 bsr.l Fib
0000000A: 584F addq.w #4,a7
0000000C: 4E75 rts
; Fib code
; --------
; Similar to the other Fib codes, but no LINK. Note that this
; affects the code. The base case doesnt jump to the end to handle
; the common return code. Instead, it returns right in the middle
; of the function. Also note that the code does unconventional
; things, such as re-using the parameter space for the first call to
; Fib to store the result of the first call. To access this value; after the second call, it must add an additional 4 to get the,
; value, since the parameter for the second fib call is on the
; stack.
00000000: 2F03 move.l d3,-(a7)
00000002: 594F subq.w #4,a7
00000004: 262F 000C move.l 12(a7),d3
00000008: 7002 moveq #2,d0
0000000A: B680 cmp.l d0,d3
0000000C: 6E08 bgt.s *+10 ; 0x00000016
0000000E: 7001 moveq #1,d0
00000010: 584F addq.w #4,a7
00000012: 261F move.l (a7)+,d3
00000014: 4E75 rts
00000016: 2003 move.l d3,d0
00000018: 5580 subq.l #2,d0
0000001A: 2F00 move.l d0,-(a7)
0000001C: 4EAD 0000 jsr Fib
00000020: 2F40 0004 move.l d0,4(a7)
00000024: 2003 move.l d3,d0
00000026: 5380 subq.l #1,d0
00000028: 2F00 move.l d0,-(a7)
0000002A: 4EAD 0000 jsr Fib
0000002E: D0AF 0008 add.l 8(a7),d0
00000032: 4FEF 000C lea 12(a7),a700000036: 261F move.l (a7)+,d3
00000038: 4E75 rts
-
8/14/2019 22Fibonacci-2.pdf
4/5
Custom Calling Convention (Cder style assembly this time)
FibProg MAIN
MOVE.L #4, -(A7)
JSR Fib
ADDQ.L #fibParamSize, A7
_ExitToShell
ENDMAIN
; Function: Fib
; -------------
; This function wraps a recursive function to compute the nth
; Fibonacci number. The wrapping is done to allow the caller to
; use C calling conventions though we don't internally use them
; (it's faster not to). The C prototype is "int Fib (int n);".
;
; Note that LINK is used though it's not strictly required.; It just makes it a bit easier to get the parameter after we've
; saved the registers.
;
; See FibRecurse for more details...
nOff EQU 8 ; A6 relative...
fibParamSize EQU 4
Fib PROC
LINK A6, #0
MOVEQ.L #2, D2
MOVE.L nOff(A6), D1
JSR FibRecurse
UNLK A6
RTS
ENDPROC
-
8/14/2019 22Fibonacci-2.pdf
5/5
; Function: FibRecurse
; --------------------
; This is a recursive function to compute the nth Fibnacci number
; using Fib(n) = Fib (n-1) + Fib (n-2). Note that Fib(1) =
; Fib(2) = 1.
;
; The function doesn't use any standard calling convention in order; to get some extra speed. The function basically uses two registers
; as input and one register as output (see below). None of the
; registers are trashed, including the parameters (though D1 is
; temporarily changed, it is restored).
;
; Note that the stack is used as a holding place for D0 before
; the second call to recurse. The function treats D0 as
; caller saved (which all C does).
;
; Inputs
; D1 (.L) -- n (the paramater to fib)
; D2 (.L) -- The constant 2 (makes comparison faster)
;
; Outputs
; D0 (.L) -- The result of the fib.
FibRecurse PROC
MOVEQ.L #1, D0
CMP.L D2, D1
BLE @FibRecDone
SUBQ.L #1, D1
JSR FibRecurse
MOVE.L D0, -(A7)
SUBQ.L #1, D1
JSR FibRecurse
ADD.L (A7)+, D0
ADDQ.L #2, D1
@FibRecDone RTS
ENDPROC