English Amiga Board


Go Back   English Amiga Board > Coders > Coders. Asm / Hardware

 
 
Thread Tools
Old 25 February 2020, 22:42   #1
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 51
Posts: 304
BPTR alignment

When I call a DOS function the pointers need to be in BCPL format, right? So what does this exactly mean? word aligned, or long?
sparhawk is offline  
Old 25 February 2020, 22:50   #2
arcanist
Registered User
 
Join Date: Dec 2017
Location: Austin, TX
Age: 37
Posts: 240
BPTRs are shifted, not just aligned. See the BADDR macro from NDK headers:

#define BADDR( bptr ) (((ULONG)bptr) << 2)

Though this is mostly an implementation detail if you don't plan to dereference the pointers.
arcanist is offline  
Old 26 February 2020, 02:08   #3
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,600
Not all pointers in dos.library functions are BCPL pointers, and not all of those pointers which are not BPTRs need 32-bit alignment. Usually this is documented.
phx is offline  
Old 26 February 2020, 07:41   #4
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 51
Posts: 304
So when I call a function like Lock() which requires a BPTR I have to take the regular address and shift it?
Because I tried to align it to a long (haven't tested it yet).
Code:
sub.l #size+4,a7
move.l a7,d1
and.b #$fc,d1
addq #4,d1
move.l d1,a0
sparhawk is offline  
Old 26 February 2020, 08:53   #5
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 49
Posts: 519
Lock() doesn't need a lock. It returns a lock.

http://amigadev.elowar.com/read/ADCD.../node0186.html

You can use that returned lock without any further processing.
alkis is offline  
Old 26 February 2020, 08:56   #6
grond
Registered User

 
Join Date: Jun 2015
Location: Germany
Posts: 738
I thought all AmigaOS pointers were long-aligned anyway (OK, A7 could be set to a word boundary; btw, are you really sure you want to do that sub on A7?). If so, all it would need to turn an AmigaOS pointer into a BPTR is:

Code:
lsr.l #2,d1
move.l d1,a0
grond is offline  
Old 26 February 2020, 10:06   #7
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 51
Posts: 304
Quote:
Originally Posted by grond View Post
I thought all AmigaOS pointers were long-aligned anyway (OK, A7 could be set to a word boundary; btw, are you really sure you want to do that sub on A7?).

That was just an example. Anyway, it's valid to create local variables on the stack, right? The compiler does it, and I use this pattern in other code as well, to avoid creating memory variables.



Quote:
If so, all it would need to turn an AmigaOS pointer into a BPTR is:

Code:
lsr.l #2,d1
move.l d1,a0
Thanks! I was unsure about that, because I thought such pointers would have to be aligned on a long word address, but just shifting them, is something different.


And alkis is right, I don't need to do this anyway, when I just get a pointer to pass around from DOS without need of dereferencing it.


It's been quite some time, since I last did Amiga Programming, so I have to relearn all that stuff again.
sparhawk is offline  
Old 26 February 2020, 10:49   #8
hooverphonique
ex. demoscener "Bigmama"

 
Join Date: Jun 2012
Location: Fyn / Denmark
Posts: 1,062
You can think of them as pointers to longs instead of bytes. Thus their value can be any integer - 0 points to long number 0 (address 0), 1 points to long number 1 (address 4), and so on..
hooverphonique is offline  
Old 26 February 2020, 11:15   #9
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 51
Posts: 304
Yes, that makes sense, and is easier to remember. Thanks for the explanation.
sparhawk is offline  
Old 26 February 2020, 13:26   #10
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 348
Quote:
Originally Posted by grond View Post
I thought all AmigaOS pointers were long-aligned anyway.
No, why? Where an object lies depends on the compiler. What is certainly true is that if you allocate memory from the Os, you'll get a pointer that pionts to an address divisible by eight. Other than that, only the 68K conventions apply, i.e. pointers are on even addresses.


Quote:
Originally Posted by grond View Post
If so, all it would need to turn an AmigaOS pointer into a BPTR is:
Code:
lsr.l #2,d1
move.l d1,a0
This means potentially shooting yourself into the foot. As rule of thumb: Pointers that go into the dos.library have to be longword aligned (e.g. struct FileInfoBlock, struct InfoData) and are long word aligned (struct CommandLineInterface, struct Process).



Many functions take BPTRs as input, and BPTRs as output, representing either a lock or a file handle. Those should be used as "opaque values", i.e. what comes out of the dos.library as BPTR can go into another function as BPTR (i.e. the output of Lock() can be an input of CurrentDir() without further modification).


It becomes touchy where the dos.library takes regular pointers (struct FileInfoBlock *). These are of course not to be divided by 4 as they are regular pointers, though most functions still expect that these pointers point to long-word boundaries.



Thus, some care needs to be taken when they are allocated on the stack or the heap to ensure proper alignment. As rule of thumb: It is for beginners advisable to just allocate such structures with AllocMem() or AllocVec() as the alignment is then correct. Putting them on the heap or the stack of the program itself requires some additional care.
Thomas Richter is offline  
Old 26 February 2020, 14:38   #11
grond
Registered User

 
Join Date: Jun 2015
Location: Germany
Posts: 738
Quote:
Originally Posted by Thomas Richter View Post
No, why? Where an object lies depends on the compiler.
That's why I wrote "AmigaOS pointers" as opposed to just "pointers". For all other pointers the user should have control anyway. As so often, everything you write in reply to my message seems to be totally unrelated to the actual subject of what was written or implied.


Quote:
This means potentially shooting yourself into the foot. As rule of thumb: Pointers that go into the dos.library have to be longword aligned (e.g. struct FileInfoBlock, struct InfoData) and are long word aligned (struct CommandLineInterface, struct Process).
Yes. And? We were specifically talking about BPTR.


Quote:
Many functions take BPTRs as input, and BPTRs as output, representing either a lock or a file handle. Those should be used as "opaque values", i.e. what comes out of the dos.library as BPTR can go into another function as BPTR (i.e. the output of Lock() can be an input of CurrentDir() without further modification).
This is more interesting. Are there cases where BPTR are somehow generated by the programmer or are there none?
grond is offline  
Old 26 February 2020, 16:27   #12
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 51
Posts: 304
Quote:
Originally Posted by grond View Post
This is more interesting. Are there cases where BPTR are somehow generated by the programmer or are there none?

That's actually exactly why I was asking. So in the meantime I looked into my "Amiga Intern" (the holy bible ) And when I want to use Examine() I must indeed make sure that I have to have an address aligned to 4, so my above code should be ok, as it aligns a block to 4. In the book, they recommend to use AllocMem() because of that, but I think this is a bit of an overhead and additional complexity for something as simple as this.


I wonder where this requirement comes from. On the first Amigas they had only the technical constraint with even address alignment, which I could understand. Apart from that, I don't see why they require this long alignment, or why AllocMem even aligns to 8.
sparhawk is offline  
Old 26 February 2020, 16:33   #13
grond
Registered User

 
Join Date: Jun 2015
Location: Germany
Posts: 738
Quote:
Originally Posted by sparhawk View Post
That's actually exactly why I was asking.
Yes, but because ThoR likes to chime in with a lot of very detailed but unrelated technical information, I wanted to present the original question to him again. He is a very knowledgable guy after all...


Quote:
I wonder where this requirement comes from.
It is some historical stuff from the OS that Amiga bought to have a starting point for their AmigaOS development. Was it called Tripos? I think it was written in BCPL, some long forgotten programming language. Somebody there thought that pointers would be able to address four times as much RAM if they were made 32bit-aligned and that it was a very clever idea. Unfortunately this resulted in a lot of unnecessary shifting around pointers...
grond is offline  
Old 26 February 2020, 18:05   #14
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 49
Posts: 519
Quote:
Originally Posted by sparhawk View Post
That's actually exactly why I was asking. So in the meantime I looked into my "Amiga Intern" (the holy bible ) And when I want to use Examine() I must indeed make sure that I have to have an address aligned to 4, so my above code should be ok, as it aligns a block to 4. In the book, they recommend to use AllocMem() because of that, but I think this is a bit of an overhead and additional complexity for something as simple as this.
You can use __aligned to declare a struct FileInfoBlock on the stack like
Code:
__aligned struct FileInfoBlock fib;
this works in gcc and SAS C.

https://franke.ms/cex/z/XR1NRA
hmm, gcc2.95 looks buggy, gcc6.5.0 looks good.

Last edited by alkis; 26 February 2020 at 18:16. Reason: compiler explorer
alkis is offline  
Old 26 February 2020, 18:14   #15
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 51
Posts: 304
Quote:
Originally Posted by alkis View Post
You can use __aligned to declare a struct FileInfoBlock on the stack like
Code:
__aligned struct FileInfoBlock fib;
this works in gcc and SAS C.
Thanks! Is there something similar for vasm as well?
sparhawk is offline  
Old 26 February 2020, 21:12   #16
jotd
This cat is no more
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 48
Posts: 3,667
you can use the great classic:

Code:
   CNOP 0,4
jotd is offline  
Old 26 February 2020, 21:34   #17
Exodous
Registered User

 
Join Date: Sep 2019
Location: Leicester / England
Posts: 36
Quote:
Originally Posted by arcanist View Post
BPTRs are shifted, not just aligned. See the BADDR macro from NDK headers:

#define BADDR( bptr ) (((ULONG)bptr) << 2)

You missed one very important point with this quotation - the comment:


Code:
#define BADDR( bptr ) (bptr << 2) * Convert BPTR to byte addressed pointer
BADDR converts a BCPL pointer to a byte addressed pointer. To go from a data address to a BCPL pointer, you shift the address right by 2, which means the data has to be long word aligned.
Exodous is offline  
Old 26 February 2020, 22:05   #18
sparhawk
Registered User

sparhawk's Avatar
 
Join Date: Sep 2019
Location: Essen/Germany
Age: 51
Posts: 304
Quote:
Originally Posted by jotd View Post
you can use the great classic:

Code:
   CNOP 0,4

But this will not work to create an aligned stack space, only memory. Or am I missing something?
sparhawk is offline  
Old 26 February 2020, 22:28   #19
phx
Natteravn

phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 1,600
Quote:
Originally Posted by grond View Post
I thought all AmigaOS pointers were long-aligned anyway
You probably wanted to say "AmigaDOS" pointers? I wouldn't expect that pointers returned by other parts of AmigaOS are longword-aligned (so I can understand ThoR's reply).

But even in dos.library you have some unaligned pointers. For example it is no problem when you call Open() with a file name on an odd address.

Quote:
(OK, A7 could be set to a word boundary;
Which leads to the more interesting question: is A7 guaranteed to be longword-aligned on program start (from Shell, from Workbench)? I think it is, but I also don't remember seeing it documented somewhere.

@sparhawk: So it would be up to you to keep the stack in 32-bit alignment (a good C compiler should do that) and don't have to care about that later.
phx is offline  
Old 27 February 2020, 01:21   #20
alkis
Registered User

 
Join Date: Dec 2010
Location: Athens/Greece
Age: 49
Posts: 519
Quote:
Originally Posted by sparhawk View Post
Thanks! Is there something similar for vasm as well?
If you click on the compiler explorer link you'll see the assembly that gcc-6.5.0 comes up with for the job. You can probably use it as a template for a macro with two arguments 1) sizeof struct 2) alignment (i.e foo 260,4)
alkis 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
Data/instruction alignment for 68020..060 phx Coders. Asm / Hardware 16 17 February 2020 20:22
vasm and word alignment Den Coders. Asm / Hardware 9 07 February 2014 11:25

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 14:46.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2020, vBulletin Solutions Inc.
Page generated in 0.09205 seconds with 15 queries