English Amiga Board


Go Back   English Amiga Board > Coders > Coders. General

 
 
Thread Tools
Old 14 March 2011, 21:29   #1
Jherek Carnelia
Dazed and Confused
 
Jherek Carnelia's Avatar
 
Join Date: Dec 2001
Location: portsmouth/uk
Posts: 242
Program Counter with Offset - why?

Right chaps, I've dusted off my old books after near-on 20 yrs of not doing anything and am going back to the begininning and re-learning (or rather, trying to) assembly programming.

Going through the addressing modes, I've come to something that puzzles me a bit; why/when you would use PC Relative with offset, for example:

...
lea P61_Quiet(PC),a3
...

what's the advantage/difference over just using

lea P61_Quiet,a3

Don't they do the same thing? I thought that all code was relocatable and thus all labels were relative (except absolute stuff like the HW registers), so why do you need to explicitly state 'label(PC),An'?
Jherek Carnelia is offline  
Old 14 March 2011, 21:58   #2
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
There was another post on this around here a couple of days ago IIRC.

They do achieve the same thing, yes.

The advantage of using PC relative addressing is that it's shorter and faster.

There are restrictions on its use: It can't be used across sections in code (without trickery anyway...) and there is a maximum displacement allowed, although again, it is possible to do some manipulation to extend the limit if you simply have to get an address pc relatively like for example to use code loaded with a non system friendly trackloader.
pmc is offline  
Old 14 March 2011, 22:12   #3
Jherek Carnelia
Dazed and Confused
 
Jherek Carnelia's Avatar
 
Join Date: Dec 2001
Location: portsmouth/uk
Posts: 242
Thx PMC. So would you say it's best to always use label(PC), unless the assembler says the label is out of range, and then just change it to label,An. I must say at the moment I can't think of an instance where I would need to use label(PC) - although in the future who knows...
Jherek Carnelia is offline  
Old 14 March 2011, 22:13   #4
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
Quote:
Originally Posted by Jherek Carnelia View Post
why/when you would use PC Relative with offset, for example:

...
lea P61_Quiet(PC),a3
...

what's the advantage/difference over just using

lea P61_Quiet,a3

Don't they do the same thing? I thought that all code was relocatable and thus all labels were relative (except absolute stuff like the HW registers), so why do you need to explicitly state 'label(PC),An'?
PC relative code is shorter and faster and it is fully relocatable without the help of the OS, i.e. you can copy it to any location in memory and it will still work without any problem. If you omit the (pc) your executable will contain RELOC entries (RELOC32 hunk) which AmigaDOS will use for relocating when the executable is loaded. That means that you can't just copy the binary anywhere into memory without coding a relocation routine or depending on AmigaDOS for loading the executable.

Edit:
Quote:
Originally Posted by Jherek Carnelia View Post
I must say at the moment I can't think of an instance where I would need to use label(PC)
Once you start size/speed optimised coding you'll easily see why pc relative coding is useful. Or when you need to copy your code around in memory for whatever reason.
StingRay is offline  
Old 14 March 2011, 22:22   #5
Jherek Carnelia
Dazed and Confused
 
Jherek Carnelia's Avatar
 
Join Date: Dec 2001
Location: portsmouth/uk
Posts: 242
Quote:
Originally Posted by StingRay View Post
PC relative code is shorter and faster and it is fully relocatable without the help of the OS, i.e. you can copy it to any location in memory and it will still work without any problem. If you omit the (pc) your executable will contain RELOC entries (RELOC32 hunk) which AmigaDOS will use for relocating when the executable is loaded. That means that you can't just copy the binary anywhere into memory without coding a relocation routine or depending on AmigaDOS for loading the executable.


Once you start size/speed optimised coding you'll easily see why pc relative coding is useful. Or when you need to copy your code around in memory for whatever reason.
Ah, I can see where that would be an advantage. Thanks for the explanation. I think that will be some way away yet...
Jherek Carnelia is offline  
Old 15 March 2011, 08:45   #6
Hewitson
Registered User
 
Hewitson's Avatar
 
Join Date: Feb 2007
Location: Melbourne, Australia
Age: 41
Posts: 3,773
So StingRay, you would recommend to use the PC whenever performing an lea?

Which other instructions should it be used with, if any.

Thanks
Hewitson is offline  
Old 15 March 2011, 10:56   #7
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,546
Quote:
Originally Posted by Hewitson View Post
So StingRay, you would recommend to use the PC whenever performing an lea?

Which other instructions should it be used with, if any.
You can use it with all instructions which also support reading from an absolute addressing mode. Good assemblers will automatically convert any absolute addressing mode to PC-relative, when possible. So you don't have to care.

Note that the PC-relative mode cannot be used for write-accesses. That makes sense, because PC-relative modes always refer to the same section as your code is running in, and the program section is usually write-protected on real operating systems.

Another technique, which also allows write-accesses, but with the speed of PC-relative addressing, is the "small data" or base-relative mode. Here you would reserve a single address register to reference all your data relative to its base address.
phx is offline  
Old 15 March 2011, 11:36   #8
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
I'm with phx on this. Skip all the extra (PC) BNE.S etc. stuff and let the assembler do that for you too. It makes your code much cleaner and easier to read, and you can specify the exact instruction in those few places where it's absolutely necessary, like PC-relative code in a bootblock or same-sized branches in a branch-table.

I'm all for optimizing code but the reality is that in almost all cases these single-instruction optimizations only result in marginal improvements to code size and execution speed, and the big gains are to be found in optimizing on algorithm level, which is another good reason to not bother with this yourself and let your assembler do this too for you, like it's supposed to do.
Leffmann is offline  
Old 15 March 2011, 12:07   #9
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
Quote:
Originally Posted by Leffmann View Post
I'm with phx on this. Skip all the extra (PC) BNE.S etc. stuff and let the assembler do that for you too. It makes your code much cleaner and easier to read,
I disagree (yeah, you didn't see that coming eh ), it is not much extra work to type (pc) and it's good practice. Why rely on the assembler to do that for you? It also means you'll have to use an optimising assembler and I for one still prefer to optimise my 68k (!) code myself. I also don't see how it makes your code more readable when you don't use pc relative modes.

Quote:
Originally Posted by Leffmann View Post
I'm all for optimizing code but the reality is that in almost all cases these single-instruction optimizations only result in marginal improvements to code size and execution speed, and the big gains are to be found in optimizing on algorithm level, which is another good reason to not bother with this yourself and let your assembler do this too for you, like it's supposed to do.
While I agree on "optimising should be done on algorithm level" I disagree that you should let the assembler do all the pc relative stuff for you. It just encourages laziness which is never good but that's just my opinion. pc relative modes are there for a reason, they aren't as useless as you make them sound.
StingRay is offline  
Old 15 March 2011, 13:23   #10
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
I agree with Stinger in relation to letting the assembler make these kind of changes - better to control it yourself.

In fact, in my own code I've gotten into the habit of always using the exact mnemonic I want, for example:

I would always use andi.w #xxxx,Dn rather than and.w #xxxx,Dn and would always do adda.w #x,An rather than add.w #x,An

In reality the assembler would amend the and.w and add.w in the two examples above to use the correct andi.w and adda.w mnemonics in the background but why let it do that...?

It doesn't take me any more time to type the correct mnemonic. Also, it's good practice to use the correct ones and kind of proves to myself that I know the difference.
pmc is offline  
Old 15 March 2011, 16:59   #11
Leffmann
 
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
Quote:
Originally Posted by StingRay View Post
it is not much extra work to type (pc) and it's good practice.
It's not about the extra work or time, but making code easier to read and follow. Exactly why is it a good practice to type (pc) but not to write easy to read code?

Quote:
Originally Posted by StingRay View Post
Why rely on the assembler to do that for you?
Why do you rely on the assembler to optimize your branches? or even to correctly translate every single line of code you write?

Quote:
Originally Posted by StingRay View Post
I also don't see how it makes your code more readable when you don't use pc relative modes.
For the same reason that Python f.ex is more readable than advanced C++. Less syntax fluff means easier to read code.

Quote:
Originally Posted by StingRay View Post
While I agree on "optimising should be done on algorithm level" I disagree that you should let the assembler do all the pc relative stuff for you. It just encourages laziness which is never good but that's just my opinion.
Then why do you f.ex write the shorthand MOVE and CMP mnemonics instead of the full MOVEA and CMPI? Why do you use macros if not out of convenience?

Quote:
Originally Posted by StingRay View Post
pc relative modes are there for a reason, they aren't as useless as you make them sound.
Of course they are useful, I never said they weren't.


Quote:
Originally Posted by pmc View Post
In reality the assembler would amend the and.w and add.w in the two examples above to use the correct andi.w and adda.w mnemonics in the background but why let it do that...?
Well, why do you type .S after your branches and let the assembler handle the rest? Why do you use section- ds- and blk-statements instead of writing them out in full or allocate memory yourself? Because it's easier to leave it to the assembler.
Leffmann is offline  
Old 15 March 2011, 18:23   #12
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Quote:
Originally Posted by Leffmann
Well, why do you type .S after your branches and let the assembler handle the rest? Why do you use section- ds- and blk-statements instead of writing them out in full or allocate memory yourself? Because it's easier to leave it to the assembler.
True. Personally however, I regard writing something like dcb.b 10,0 instead if dc.b 0,0,0,0,0,0,0,0,0,0 as something very different to allowing the assembler to quietly amend my code in the background for me.

I suppose though, it just all comes down to personal preference at the end of the day.
pmc is offline  
Old 15 March 2011, 19:18   #13
Galahad/FLT
Going nowhere
 
Galahad/FLT's Avatar
 
Join Date: Oct 2001
Location: United Kingdom
Age: 50
Posts: 9,017
I handle all optimisations myself.

I've had problems in the past where i've let an assembler optimise, and its ended up optimising an instruction I don't want to touch as it will affect something and cause a bug.

The fact my code is invariably littered with PC or .s or whatever, I find just as easy to read.

I can go back to highly optimised code I wrote years ago and instantly know whats happening.
Galahad/FLT is offline  
Old 15 March 2011, 21:59   #14
StingRay
move.l #$c0ff33,throat
 
StingRay's Avatar
 
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
Quote:
Originally Posted by Leffmann View Post
It's not about the extra work or time, but making code easier to read and follow. Exactly why is it a good practice to type (pc) but not to write easy to read code?
You don't really want to tell me that (pc) makes the code harder to read, do you? And it is good practice to use pc relative addressing whenever you can for reasons already mentioned. How that makes code harder to read is beyond me. Pc relative addressing modes are part of the 68k syntax so if you really say that it makes the code harder to read when one uses these modes it implies that you don't fully know the 68k instruction set.
The only reason for me to omit (pc) is laziness, nothing else.

Quote:
Originally Posted by Leffmann View Post
Why do you rely on the assembler to optimize your branches? or even to correctly translate every single line of code you write?
I don't rely on the assembler to optimise my branches! As for your other argument, well, that's what an assembler is for and has absolutely nothing to do with letting the assembler optimise code. You could as well ask me why I expect a car to drive when I started the engine. Same logic.

Quote:
Originally Posted by Leffmann View Post
Then why do you f.ex write the shorthand MOVE and CMP mnemonics instead of the full MOVEA and CMPI? Why do you use macros if not out of convenience?
I use macros that I created MYSELF, do you see the difference? I know exactly what they are doing because I (!) created them, not an assembler.

Quote:
Originally Posted by Leffmann View Post
Of course they are useful, I never said they weren't.
The way you discuss here makes me think otherwise.


Quote:
Originally Posted by Leffmann View Post
Well, why do you type .S after your branches and let the assembler handle the rest? Why do you use section- ds- and blk-statements instead of writing them out in full or allocate memory yourself? Because it's easier to leave it to the assembler.
I don't use .s because I consider that incorrect (in the same way I consider "dbra" incorrect too), I use .b for branches in byte range. But that's just an aside. Over to your next argument, the section thing, instead of answering your question I ask you another question: Why do you use the gearbox in a car to shift? Why do you use the accelerator pedal when you want to accelerate a car? Because that is how a car works even though there would be other ways to achieve the same results. And it's the same for using the ds.x pseudo opcodes or SECTION statements. It can be considered a standard feature of any assembler, you really have to look hard to find one which won't allow you to use one of these things (and no, SEKA doesn't count!). And it still can't be compared to letting the assembler optimise your code because that is something completely different! When I use a Section statement or reserve space with ds.x I still know EXACTLY how my code will look like, when I let the assembler optimise my code because I am too lazy to do it myself then I don't know how the final code that'll be generated looks like. Besides, what if you need 100% pc relative code and your assembler has no way to optimise your code that way? Then you'll have to change your code manually anyway and you won't save any time.
StingRay is offline  
Old 15 March 2011, 23:00   #15
Wepl
Moderator
 
Wepl's Avatar
 
Join Date: Nov 2001
Location: Germany
Posts: 876
I'm with Leffmann here.
All optimizations which can be done by the assembler should be done by the assembler. The programmer should create short and best readable code without any unnecessary decoration. He also should use the best available tools. Optimizing branches, pc-relative and similar stuff by hand is in IMHO disproductive. And a good assembler tells you about every optimization it does and if the code is position independed or not.
In question I use a reassembler or debugger anyway to look at the generated code.
I use dbf
Wepl is offline  
Old 16 March 2011, 00:13   #16
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,658
There is one benefit of using optimization, and that is that you don't have to type the exact addressing mode or mnemonic (code looks more homogeneous and can be re-used as is without having to type AO or check PC-relativity range.)

Now, where there is only one choice (f.ex. dbf, addi #, adda Dn,An) it only changes some bits in the resulting hexcode, which rarely (never) affects anything. And there's only one choice, so the only result from enforcing exact opcodes would be a little trickier typing and losing support in a few old assemblers. That's where it's handy.

But relying on the assembler to take care optimization will yield a source that will need to be intelligently hand-optimized for those who choose an assembler they like better that doesn't have it (or has it as option or command). What is run in his assembler then could be different, and even break tight code.

So, pseudo-code that affects nothing vs. pseudo-code that affects code size and speed. Two different kinds.


The major drawbacks of auto-optimization:
- only a many-to-many algorithm where you select many "pristine areas" of the code could be a perfect optimization algorithm. There have been more than a few times where a selective mix (by me) of word and byte branches in a tight loop has yielded a better result than an algorithm could hope to achieve.

- you have to turn it off for jump tables (one type of pristine area) or salute the guru.


The benefits of (PC) and bcc.s:
- you know more about your code by reading it; that label is near me, that variable is in this section
- what you write is what you run: no pseudocode, no surprises in the disassembler after hunting for a bug in your code that was in fact in the binary.
- saving A-regs and leas with inline tables: move.b MaskTable(PC,d0.w),d0
- codesize-dependant offsets can make a piece of code easier to write, or macroize, or repeat (no label-numbering hooplah or assembler-dependant 'increased offset-symbols'. A macro cryptic as hell and 16 lines instead of 8 lines of plain code? Plain code for me!
- by making a piece of code relocatable without the OS, you also have the benefit of assembling includable binaries once and never have to assemble them again.



Use (PC) etc for code that needs to be optimized, and don't bother if size or speed isn't important. That's what I do.

For optimized code I even use A5 as a base register near the code, to use like (PC) but for writes without having to lea first.

But for all other code I don't give a damn if the code is slow or messy, as long as it's bug-free and readable. I don't even use customregister(a6).


But usually the habit prevails and all code is exact, especially since I have "(PC)" etc bound to quick-keys since 1991, I'm used to it and it's no bother for me.


If you never need to write super tight code or write OS-only code, don't sweat it, it will be fast and small enough. Macros are good both for super-tight, hardware-banging code, OS-only code and slow/big code. And making data. I use them every time the need appears. Macros are

Last edited by Photon; 16 March 2011 at 00:25.
Photon is offline  
Old 16 March 2011, 00:34   #17
Djay
95th User
 
Djay's Avatar
 
Join Date: May 2001
Location: Brighton/UK
Age: 48
Posts: 3,120
off-topic
i have no idea what you guys are talking about but it is fascinating to read "programmer talk", i only really played about with basic and C++ myself

i do have a question though... there seems to be alot of talk about writing code on the Amiga, what are you guys coding? are you just mucking about with routines or are you actually working on projects?

back on topic...
Djay is offline  
Old 16 March 2011, 09:05   #18
pmc
gone
 
pmc's Avatar
 
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
Djay: I'm actually coding demo type stuff all the time - just finished two things that will soon be released, one explicitly, the other hidden away somewhere...

Nothing I code is gonna shake the scene but it's all fun.

On topic - I'm a recent convert to using both dbf instead of dbra and .b instead of .s - goes back to the accuracy and "correctness" I've been trying to follow when writing my code as I described a few posts back.
pmc is offline  
Old 16 March 2011, 12:13   #19
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,546
Quote:
Originally Posted by StingRay View Post
The only reason for me to omit (pc) is laziness, nothing else.
While I have to admit that I write (pc) most of the time, there are also reasons to omit it. It makes it easier to restructure your code and move lables around, even into different sections, and the assembler will automatically choose PC-relative or absolute. Or you could choose to move those labels into a small data section and the assembler will automatically append (An).

Quote:
I don't rely on the assembler to optimise my branches!
Really!?
I cannot believe that this would result in perfectly optimized code. Do you always count all instruction sizes between your labels to decide if it is a Bcc.B or Bcc.W?

I understand your concerns though, that you want full control about the generated code. But even with full optimization enabled you still can control the optimizer, by writing the extension yourself or not. For example: BRA.W will never be optimized. A BRA (without extension) would. A MOVE (100.L,A0) would never be optimized. A MOVE (100,A0) would.


Quote:
I don't use .s because I consider that incorrect (in the same way I consider "dbra" incorrect too), I use .b for branches in byte range.
Absolutely correct!
phx is offline  
Old 16 March 2011, 21:06   #20
Photon
Moderator
 
Photon's Avatar
 
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,658
As a humorous twist I may offer:

"I sure hope none of you auto-optimizing dudes use BOTH bra and jmp in your programs!!" Hehehe...
Photon is offline  
 


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

Similar Threads
Thread Thread Starter Forum Replies Last Post
blizzard 1230 MkII plcc counter chip arizz support.Hardware 1 12 April 2022 23:29
External windows program communicating with program running inside WinUAE xxxxx support.WinUAE 10 19 February 2013 09:27
WHDLoad - NTSC and screen offset Anubis project.WHDLoad 4 27 January 2010 21:20
GfxRip Palette and Offset questions stef80 project.Sprites 2 06 July 2007 19:59
Evaluate a location on floppy disk by offset? (t/h/s) andreas Coders. General 11 23 June 2005 12:03

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 23:08.

Top

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