[comp.sys.amiga.programmer] 68K Assembly language question

dlbres14@pc.usl.edu (Brumley David M) (02/21/91)

The following example of stack frame parameter passing is taken from
_68000 Assembly Language:  Techniques for Building Programs_ by Donald
Kranz and James Stanley, Addison-Wesley:  Reading, Mass.  1986.  p 121.

"Let's look at a hypothetical routine 'max' that incorporates two of
the uses of a stack frame.  This routine is passed two 16-bit integer
values, and returns the larger of the two in register D0.   If the two
numbers are equal, we assume catastrophic failure elsewhere and call a
routine walkback that will display the walkback sequence.  [The
walkback stuff is irrelevant to my question.]  The code calling 'max'
might look like this:

MOVE.W  D0,-(A7)	* Push parameter 1 on stack
MOVE.W  D1,-(A7)	* Push parameter 2 on stack
BSR	MAX		* Call 'max'


The code for 'max' could look like this:

MAX:	LINK	A6,-4		* LINK and make 4 byte extra space
	MOVE.L  #MX,-4(A6)	* Put address of name in frame
	MOVE.W	8(A6),D0	* Get parameter 1 to D0     <--- ???
	CMP.W 	10(A6),D0	* Test against parameter 2  <--- ???
	BEQ	WALKBACK	* Do walkback if equal
	BLT	IS_P2		* Jump if P2 > P1
	BRA	EXIT		* P1 > P2
IS_P2:	MOVE.W	10(A6),D0	* Put parameter 2 into D0    
EXIT:	UNLK	A6		* Unlink frame
	RTS			* Get out of routine
MX:	DC.B	'MAX',0		* Name for walkback

[...]"

Ok, my question has to do with the lines:

	MOVE.W	8(A6),D0	* Get parameter 1 to D0     
	CMP.W 	10(A6),D0	* Test against parameter 2 

I simply don't understand how 8(A6) references parameter 1 and 10(A6)
references parameter 2 when param1 was pushed onto the stack before
param2!  Of course, this is irrelevant to the correct operation of
MAX; it will return the correct value in D0 (or start the walkback to
trace the error), but the authors' comments seem misleading.  Have I
got 68K stacks all wrong?




--
David M. Brumley
<dmb8515@usl.edu>

dillon@overload.Berkeley.CA.US (Matthew Dillon) (02/23/91)

In article <DLBRES14.91Feb21073854@pc.usl.edu> dlbres14@pc.usl.edu (Brumley David M) writes:
>...
>
>MOVE.W  D0,-(A7)       * Push parameter 1 on stack
>MOVE.W  D1,-(A7)       * Push parameter 2 on stack
>BSR	MAX		* Call 'max'
>
>..
>
>MAX:	LINK	A6,-4		* LINK and make 4 byte extra space
>	MOVE.L	#MX,-4(A6)      * Put address of name in frame
>	MOVE.W	8(A6),D0        * Get parameter 1 to D0     <--- ???
>	CMP.W	10(A6),D0       * Test against parameter 2  <--- ???

>Ok, my question has to do with the lines:
>
>	MOVE.W	8(A6),D0        * Get parameter 1 to D0
>	CMP.W	10(A6),D0       * Test against parameter 2
>
>I simply don't understand how 8(A6) references parameter 1 and 10(A6)
>references parameter 2 when param1 was pushed onto the stack before
>param2!  Of course, this is irrelevant to the correct operation of
>MAX; it will return the correct value in D0 (or start the walkback to
>trace the error), but the authors' comments seem misleading.  Have I
>got 68K stacks all wrong?

    The stack looks like this:

	[pushed D0]
	[pushed D1]
	[RETURN PC]
 sp->	[LINK-SAVE-A6]

    thus, 0(A6) references the saved link register, A6, 4(A6) references
    the return-pc (from the BSR), and 8(A6) points to D1, and 10(A6)
    points to D0 ... the 'parameter 1' and 'parameter 2' comments are
    mixed up .... 8(A6) is D1, or parameter 2 by the first definition.

    If you relate this to C you should note that C always pushes parameters
    in reverse order, so parameter 1 would be pushed LAST, thus 8(A6)
    would be parameter one and 10(A6) parameter 2, etc... in C (16 bit
    compilation).

>--
>David M. Brumley
><dmb8515@usl.edu>

--
					-Matt

    Matthew Dillon	    dillon@Overload.Berkeley.CA.US
    891 Regal Rd.	    uunet.uu.net!overload!dillon
    Berkeley, Ca. 94708
    USA

scroll@reef.cis.ufl.edu (Steve Croll) (02/23/91)

In article <DLBRES14.91Feb21073854@pc.usl.edu> dlbres14@pc.usl.edu (Brumley David M) writes:
>Ok, my question has to do with the lines:
>
>	MOVE.W	8(A6),D0	* Get parameter 1 to D0     
>	CMP.W 	10(A6),D0	* Test against parameter 2 
>
>I simply don't understand how 8(A6) references parameter 1 and 10(A6)
>references parameter 2 when param1 was pushed onto the stack before
>param2!

The references are backwards.  Assuming a7 contained $4000 before the
parameters where pushed, the following stack frame exists immediately
after the link instruction.

$4000
$3FFE <contents of d0.w> ; parameter 1, reference with 10(a6)
$3FFC <contents of d1.w> ; parameter 2, reference with  8(a6)
$3FF8 <return address>
$3FF4 <frame pointer>    ; 'old' a6
$3FF0 <unitialized local storage>

a7 contains $3FF0, a6 contains $3FF4

Note: if your are interfacing C with assembly, parameters are
generally pushed in REVERSE order.  For example, when the call to 
function foo(x,y,z) is made, z is pushed on the stack first, y is pushed
on next, and finally z is pushed on the stack.

-- 
--
Steve Croll (internet: scroll@reef.cis.ufl.edu  home: 904-373-8389)

dlbres14@pc.usl.edu (Brumley David M) (02/28/91)

In article <dillon.4189@overload.Berkeley.CA.US> dillon@overload.Berkeley.CA.US (Matthew Dillon) writes:

       The stack looks like this:

	   [pushed D0]
	   [pushed D1]
	   [RETURN PC]
    sp->   [LINK-SAVE-A6]

       thus, 0(A6) references the saved link register, A6, 4(A6) references
       the return-pc (from the BSR), and 8(A6) points to D1, and 10(A6)
       points to D0 ... the 'parameter 1' and 'parameter 2' comments are
       mixed up .... 8(A6) is D1, or parameter 2 by the first definition.

       If you relate this to C you should note that C always pushes parameters
       in reverse order, so parameter 1 would be pushed LAST, thus 8(A6)
       would be parameter one and 10(A6) parameter 2, etc... in C (16 bit
       compilation).

which makes a lot more sense and suggests the authors' were in error.
Too bad, otherwise, I like the style of Krantz and Stanley's _68000
Assembly Language: Techniques for Building Programs_.  Any
recommendations for other texts that describe the MC680x0 assembly
language at an introductory->intermediate level?

--
David M. Brumley
<dmb8515@usl.edu>