Reserving space on the stack with an subroutine

All 680x0 related coding posts in this section please.

Moderators: simonsunnyboy, Mug UK, Zorro 2, Moderator Team

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5129
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Reserving space on the stack with an subroutine

Postby simonsunnyboy » Thu Aug 11, 2011 3:37 pm

Hello together,

I wonder how can I safely declare stack space for variables from within a subroutine in assembly language?

Is this the proper way? (It should be reentrant!)

Code: Select all

mysub:
  movem.l   d0-a6,-(sp)  ; save registers
  subq.w #2,sp  ; get one word on stack
  ; do stuffs here
  move.w d0,(sp) ; use space on stack...

  addq.w #2,sp ; give stack space back
  movem.l (sp),d0-a6 ; restore registers
  rts


Any useful ideas or techniques?

Thanks!
ssb
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

User avatar
daeghnao
Captain Atari
Captain Atari
Posts: 479
Joined: Wed Oct 27, 2004 12:41 pm
Location: York, UK
Contact:

Re: Reserving space on the stack with an subroutine

Postby daeghnao » Fri Aug 12, 2011 7:43 am

simonsunnyboy wrote:Hello together,

I wonder how can I safely declare stack space for variables from within a subroutine in assembly language?



I'm a bit rusty, but I seem to recall that this is what the instructions link and unlk are for. You use link to create space:

Code: Select all

        link    a6,#-20


and when you want to exit you unlk the space:

Code: Select all

        unlk    a6


What link does is, it pushes the register onto the stack, then stores the stack pointer in that register, then adjusts the stack pointer. So you can now store your local variables above the stack pointer, either by indexing up from the stack pointer or down from the register you used (commonly called a frame pointer).

What unlk does is, it copies the stored stack pointer from the register back to the stack pointer register, then pops the previous value of the register from where it was stored.

ijor
Hardware Guru
Hardware Guru
Posts: 3811
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: Reserving space on the stack with an subroutine

Postby ijor » Fri Aug 12, 2011 1:21 pm

LINK UNLK are very simple to use, but they are somewhat expensive, and you "waste" one register. You can manipulate and access the SP register directly, if you know what you are doing. The latter method is a bit complicated if this subroutine, in turn, pushes parameters on the stack.

User avatar
daeghnao
Captain Atari
Captain Atari
Posts: 479
Joined: Wed Oct 27, 2004 12:41 pm
Location: York, UK
Contact:

Re: Reserving space on the stack with an subroutine

Postby daeghnao » Sat Aug 13, 2011 7:29 am

ijor wrote:LINK UNLK are very simple to use, but they are somewhat expensive, and you "waste" one register. You can manipulate and access the SP register directly, if you know what you are doing. The latter method is a bit complicated if this subroutine, in turn, pushes parameters on the stack.


Good observation. LINK/UNLK are really convenient for compiler writers, and they're not bad as a way of starting to add some rigour to a program. Easy enough to switch to something more streamlined if your code needs it. Now, if you already know in advance that you need every last cycle - and let's face it, we often do with the ST - then you probably do want to be going for the direct approach.

User avatar
Nyh
Atari God
Atari God
Posts: 1496
Joined: Tue Oct 12, 2004 2:25 pm
Location: Netherlands

Re: Reserving space on the stack with an subroutine

Postby Nyh » Mon Aug 15, 2011 2:02 pm

daeghnao wrote:Good observation. LINK/UNLK are really convenient for compiler writers, and they're not bad as a way of starting to add some rigour to a program. Easy enough to switch to something more streamlined if your code needs it. Now, if you already know in advance that you need every last cycle - and let's face it, we often do with the ST - then you probably do want to be going for the direct approach.

The LINK and UNLK are two horrible commands. You don't need them for you assembly subroutines, they make your code unnecessary complex. Compilers don't need them either. The bookkeeping for knowing where variables are relative to an address register is just as complex as keeping track of where the are relative to the stack pointer. A good compiler, like Pure C, doesn't use LINK and UNLK.

Simonsunnyboy is right to use subq.w #2,sp to get some space on the stack. When you need more just use lea to get a bigger chunk on the stack.

Hans Wessels

User avatar
simonsunnyboy
Moderator
Moderator
Posts: 5129
Joined: Wed Oct 23, 2002 4:36 pm
Location: Friedrichshafen, Germany
Contact:

Re: Reserving space on the stack with an subroutine

Postby simonsunnyboy » Mon Aug 15, 2011 3:26 pm

I was aware about the LINK command, I have used it in the past, but not to offset the SP, but to load the start of the stack frame of a given commandline into an address register.

Guess for small things, I will continue to use the method "by hand".

For the actual problem where I needed this, I found a workaround for using the registers a bit different and so I didn't need another local variable.

Thanks for your input! :)

PS: I leave the thread open, maybe more ideas and comments do surface.
Simon Sunnyboy/Paradize - http://paradize.atari.org/

Stay cool, stay Atari!

1x2600jr, 1x1040STFm, 1x1040STE 4MB+TOS2.06+SatanDisk, 1xF030 14MB+FPU+NetUS-Bee

ijor
Hardware Guru
Hardware Guru
Posts: 3811
Joined: Sat May 29, 2004 7:52 pm
Contact:

Re: Reserving space on the stack with an subroutine

Postby ijor » Tue Aug 23, 2011 4:20 am

Nyh wrote:The LINK and UNLK are two horrible commands. You don't need them for you assembly subroutines, they make your code unnecessary complex. Compilers don't need them either.


I think this is a bit of an overstatement. Yes, compilers don't need them, and as I said, they are expensive, and it is perfectly possible to get along without them. But they might be useful. They create a nice stack frame that is easy to walk backwards, very useful for debugging.

The bookkeeping for knowing where variables are relative to an address register is just as complex as keeping track of where the are relative to the stack pointer.


This is not always true. If you use the stack pointer in the code (say, you push parameters in the stack), then keeping track of the offset from the SP is more difficult than using a specific address frame pointer that is not changing.


Social Media

     

Return to “680x0”

Who is online

Users browsing this forum: No registered users and 3 guests