English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 26 June 2008, 08:31   #1
BippyM
Global Moderator
 
BippyM's Avatar
 
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
Lnk/Unlnk

Now I don't totally understand these commands other than they create temp workspace (Sounds like a procedure in c/basic)

If so why?

The game I am WHDloading (Croak) is a complete game of lnk/unlk. every single routine is contained in one of these.. the game was written in C!

I need lots of detailed info to understand thanks
BippyM is offline  
Old 26 June 2008, 09:24   #2
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
From what I understand from what I've read LINK/UNLK is there to make it easier to manage the stack in situations where subroutines call other subroutines that call other subroutines and so on where each of these subroutines needs space to store temporary data.

LINK/UNLK lets you store the temporary data on the stack itself but still maintain the integrity of the stack correctly for returns from those subroutines.

LINK allocates a frame of memory (in bytes) on the stack and sets an address register as a pointer to that stack frame.

link <address reg>,#-<value in bytes>

The negative size of the value in bytes is cos the stack grows downwards. The values in bytes is a 16 bit signed number so max size of one stack frame is 32Kb.

Each link command saves the address register used in the link command on the stack, then moves the value in the stack pointer to the address register and then subtracts the value in bytes from the stack pointer to grow the stack by that amount.

Using an example address register of a5 and an example frame size of 512 bytes, link does this:

move.l a5,-(a7)
movea.l a7,a5
addq.l #-512,a7

The frame of memory created by link is now the space between the address register used in the link command and the current value of the stack pointer.

Temporary data can be stored in this frame by moving data to where the address register is pointed to and the stack can also be used as normal without affecting this temporary frame data.

An unlk command deallocates the frame space and restores the stack pointer.

So, you can link space, call a subroutine, link more space if needed and then unlk space before returning control to the previous subroutine which can then in turn unlk its space and return from where it was called and each time the integrity of the stack is maintained.

Sounds like your game maybe has lots of subroutines that all call each other and they've used link/unlk to make the stack management easier.

Not sure if this helps in any way whatsoever but I hope it's helped you out!

Last edited by pmc; 26 June 2008 at 09:31.
pmc is offline  
Old 26 June 2008, 13:26   #3
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Nothing much to understand here, LINK/UNLK are for creating local workspace so subroutines that have to be re-entrant (or are just written in C or any other high level language) work correctly. If you don't write recursive/re-entrant routines, you can safely ignore these commands as you don't need them anyway. Pus, what PMC said except for the addq.l #-512,a7 bit (addq only works with 3 bit values where value >0 and <=8)
StingRay is offline  
Old 10 July 2008, 13:30   #4
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
I've got a question about this. If I setup some variables (for want of a better word) like this:

var1: dc.w $1234
var2: dc.l $12345678
var3: dc.l $12345678
var4: dc.b $12
var5: dc.b $34
var6: dc.l $12345678
var7: dc.l $12345678

then link some space:

link a4,#-20

and move the variables into the linked space like this:

move.w var1,(a4)
move.l var2,2(a4)
move.l var3,6(a4)
move.b var4,10(a4)
move.b var5,11(a4)
move.l var6,12(a4)
move.l var7,16(a4)

is it then faster (although, admittedly, less readable) later on in my code to do things like this:

move.l $9abcdef0,2(a4)

instead of things like this:

move.l $9abcdef0,var2

Just curios - I'm trying to work out ways to make code quicker. While I'm on the subject of optimsation, is there a list of optimisations anywhere, such as "instead of clr.l d0, do a moveq.l #0,d0 cos it's faster..."?
pmc is offline  
Old 10 July 2008, 13:32   #5
BippyM
Global Moderator
 
BippyM's Avatar
 
Join Date: Nov 2001
Location: Derby, UK
Age: 48
Posts: 9,355
I'm guessing it'd be the same speed as it will be using the same ram, though I guess it might be closer together
BippyM is offline  
Old 10 July 2008, 13:59   #6
musashi5150
move.w #$4489,$dff07e
 
musashi5150's Avatar
 
Join Date: Sep 2005
Location: Norfolk, UK
Age: 42
Posts: 2,351
Quote:
Originally Posted by pmc View Post
is it then faster (although, admittedly, less readable) later on in my code to do things like this:

move.l $9abcdef0,2(a4)

instead of things like this:

move.l $9abcdef0,var2
Yes, because the var2 is stored as a full 32bit address so it takes longer to fetch the instruction from memory as there is more of it... if that makes sense.

It would be saved as: move.l $9abcdef0,$xxxxxxxx with the $xxxxxxxx being filled in just before running by the AmigaDOS relocator.

Although if these instructions are outside a main loop in reality there won't be much difference of course.
musashi5150 is offline  
Old 10 July 2008, 14:08   #7
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
musashi5150 is right! Use relative offsets whenever possible! Faster than using absolute 32 bit values.

Quote:
move.w var1,(a4)
move.l var2,2(a4)
move.l var3,6(a4)
move.b var4,10(a4)
move.b var5,11(a4)
move.l var6,12(a4)
move.l var7,16(a4)
You can still have readable code using that approach, just define a structure like:

Code:
        RSRESET
s_var1: rs.w 1
s_var2: rs.l 1
s_var3: rs.l 1
s_var4: rs.b 1
.... etc
then you can use: move.w var1,s_var1(a4), move.l var2,s_var2(a4) etc.
StingRay is offline  
Old 10 July 2008, 14:20   #8
Toni Wilen
WinUAE developer
 
Join Date: Aug 2001
Location: Hämeenlinna/Finland
Age: 49
Posts: 26,523
Very simple 68000 rule: instruction takes at least "length of instruction in words" + "number of byte or word accesses, 1 byte = 1 word. 1 long = 2x word" memory cycles to complete.

(complex instructions like mul and addressing modes like -(ax) etc need more time. Or check the official 68000 pdf documentation, it includes timings.)

1 memory cycle is 1/4 of CPU clock on 68000 Amiga.
Toni Wilen is online now  
Old 10 July 2008, 14:46   #9
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
@bippym: yeah, you're right they'll all still be RAM locations but I was anticipating that the increase in speed would come from referencing an offset of an address register cos it's faster to use registers than memory locations.

@mushash5150: watcha mate, good to hear from you - thanks for the confirmation. Yeah, I was aiming for these accesses to be in a main program loop hence setting them up first, and then accessing them on the offsets later.

@StingRay: OK cool, so instead of linking space on the stack to an address register and then accessing offsets from that, I can setup an rs.x structure in the assembler and do the same. I take it I have to point an address register at this rs.x structure somewhere early on in my code so I can then use the offsets from that register later?

@Toni: OK thanks for the info. If I was being very lazy though (), does anyone know if some kind soul has already worked all these time saving equivalents out and published a list somewhere?
pmc is offline  
Old 10 July 2008, 15:01   #10
musashi5150
move.w #$4489,$dff07e
 
musashi5150's Avatar
 
Join Date: Sep 2005
Location: Norfolk, UK
Age: 42
Posts: 2,351
Yeah, good to see you still playing around with metal banging Both of these are fairly interesting for optimising ideas - I bet Sting knows of better ones (Or just his voodoo 68k skills )

http://linux.cis.monroeccc.edu/~paul...c/trick68k.htm
http://www.mways.co.uk/amiga/howtoco...optimising.php
musashi5150 is offline  
Old 10 July 2008, 15:11   #11
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Quote:
Originally Posted by pmc View Post
@StingRay: OK cool, so instead of linking space on the stack to an address register and then accessing offsets from that, I can setup an rs.x structure in the assembler and do the same. I take it I have to point an address register at this rs.x structure somewhere early on in my code so I can then use the offsets from that register later?
Both works, you can use a base register like a5 and point it to your variable block or you can use LINK/UNLK approach.

the first approach would be something like this:
Code:
lea	VARS(pc),a5
move.l	#$08154711,BORING(a5)
move.l	#$B00BBABE,STILL_BORING(a5)
...

VARS            RSRESET
BORING		rs.l 1
STILL_BORING	rs.l 1
VARS_SIZE	rs.b 0
		ds.b VARS_SIZE    ; important! space for the variables
The LINK/UNLK method would be like this:
Code:
link	a5,#-VARS_SIZE
move.l	#$08154711,BORING(a5)
move.l	#$B00BBABE,STILL_BORING(a5)
...
unlk	a5

VARS		RSRESET
BORING		rs.l 1
STILL_BORING	rs.l 1
VARS_SIZE	rs.b 0


Notice that you don't have to reserve space for the variables here as you do that with the LINK instruction.

Using these structures has also quite a big advantage: imagine you once change your variables, f.e. you remove the BORING variable (as you are not bored anymore :P), using the structure you can just delete it and that's all you have to do as the assembler automatically calculates the right offsets. If you would have used move.l #xxx,4(a5) you would have to change that everywhere in the source as 4(a5) is now 0(a5) for obvious reasons. I hope that was somewhat understandable.
StingRay is offline  
Old 10 July 2008, 15:21   #12
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
@musashi5150: nice one mate, I'll check those out.

@StingRay: Top man. Yeah, it was definitely understandable - and very timely, I was only looking at my code and thinking "if I ended up in a situation where I was having to change all those offsets it would be a pain in the arse!" and here you come posting the solution.
pmc is offline  
Old 10 July 2008, 15:27   #13
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,863
Perfect timing then. Happy coding =)
StingRay is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 20:06.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.08290 seconds with 12 queries