14 March 2011, 21:29 | #1 |
Dazed and Confused
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'? |
14 March 2011, 21:58 | #2 |
gone
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. |
14 March 2011, 22:12 | #3 |
Dazed and Confused
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...
|
14 March 2011, 22:13 | #4 | |
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
Quote:
Edit: 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. |
|
14 March 2011, 22:22 | #5 | |
Dazed and Confused
Join Date: Dec 2001
Location: portsmouth/uk
Posts: 242
|
Quote:
|
|
15 March 2011, 08:45 | #6 |
Registered User
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 |
15 March 2011, 10:56 | #7 | |
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,552
|
Quote:
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. |
|
15 March 2011, 11:36 | #8 |
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. |
15 March 2011, 12:07 | #9 | ||
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
Quote:
Quote:
|
||
15 March 2011, 13:23 | #10 |
gone
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. |
15 March 2011, 16:59 | #11 | |||
Join Date: Jul 2008
Location: Sweden
Posts: 2,269
|
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?
Why do you rely on the assembler to optimize your branches? or even to correctly translate every single line of code you write? Quote:
Quote:
Quote:
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. |
|||
15 March 2011, 18:23 | #12 | |
gone
Join Date: Apr 2007
Location: completely gone
Posts: 1,596
|
Quote:
I suppose though, it just all comes down to personal preference at the end of the day. |
|
15 March 2011, 19:18 | #13 |
Going nowhere
Join Date: Oct 2001
Location: United Kingdom
Age: 50
Posts: 9,020
|
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. |
15 March 2011, 21:59 | #14 | |||
move.l #$c0ff33,throat
Join Date: Dec 2005
Location: Berlin/Joymoney
Posts: 6,865
|
Quote:
The only reason for me to omit (pc) is laziness, nothing else. Quote:
Quote:
The way you discuss here makes me think otherwise. 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. |
|||
15 March 2011, 23:00 | #15 |
Moderator
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 |
16 March 2011, 00:13 | #16 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,683
|
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. |
16 March 2011, 00:34 | #17 |
95th User
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... |
16 March 2011, 09:05 | #18 |
gone
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. |
16 March 2011, 12:13 | #19 | ||
Natteravn
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,552
|
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 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:
|
||
16 March 2011, 21:06 | #20 |
Moderator
Join Date: Nov 2004
Location: Eksjö / Sweden
Posts: 5,683
|
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... |
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 |
|
|