English Amiga Board


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

 
 
Thread Tools
Old 16 July 2017, 13:40   #41
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by phx View Post
Chances are good, as long as you manage to create a correct hunk-format library (join several objects).
Ok, I did a little test expanding on my previous code (attached), only adding a routine to represent an unsigned word. This routine is pretty long, probably way longer than needed, but it should serve our purpose well, as we should see a clearer effect on the file size depending on wether we use it or not.

Here are the sizes of the executable and it's object file:
Code:
With UWordRep:
.o:   816
.exe: 780
Without UWordRep:
.o:   788
.exe: 768
So it appears that the exe itself only becomes 12 bytes smaller when we leave out UWordRep (by commenting both the xref and the actual jsr to it). So it'd say this is not working as we hoped it would. The difference in sizes of the object files, however, is bigger: 28 bytes, but probably still not enough to imply that UWordRep is really not linked in.

I'm unsure on how to proceed, as I don't really know how to 'join several objects'. Only thing I can think of, is putting both UByteRep and UWordRep into their separate files, compiling them and then linking them into stringUtil.lib. Or do I need an actual join command?

On a side note: when I compile stringUtil.lib, vasm says 'CODE(acrx2): 152 bytes'. It then generates a file of 280 bytes. Almost everything in that file is code (I think), so how does that compute?

Yep, it's asking-stupid-questions-time again, people, so gather 'round..
Attached Files
File Type: zip PrintDecimal2.zip (1.8 KB, 59 views)
guy lateur is offline  
Old 16 July 2017, 13:52   #42
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Source code is missing. But I bet you have UWordRep and UByteRep in the same file producing a single .o. Split them in two files. Make two .o files. Try (cause you don't have a compiler set, I guess) join uwordrep.o ubyterep.o to foo.lib and link against foo.lib and redo your exe size checks.
alkis is offline  
Old 16 July 2017, 13:55   #43
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
or try adding -gc-all -gc-empty to vlink's parameters.
alkis is offline  
Old 16 July 2017, 14:02   #44
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
Source code is missing. But I bet you have UWordRep and UByteRep in the same file producing a single .o. Split them in two files. Make two .o files. Try (cause you don't have a compiler set, I guess) join uwordrep.o ubyterep.o to foo.lib and link against foo.lib and redo your exe size checks.
Can you not access the attachment? Because I can download it here no problem.

And yes, both functions are in the same file ATM. I will definitely try your suggestions, in reverse orde.. Thanks!
guy lateur is offline  
Old 16 July 2017, 14:34   #45
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
or try adding -gc-all -gc-empty to vlink's parameters.
Ok, I've tried this first, obviously, but unfortunately this doesn't seem to change anything; I'm getting the exact same numbers (with and without) as before.

I'll try the '1 subroutine per file' approach next.
guy lateur is offline  
Old 16 July 2017, 15:10   #46
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Ok, I've separated the subroutines into their own file. Here's how I create the lib:
Code:
vasm stringUtilUByteRep.asm -o stringUtilUByteRep.o -Fhunk
vasm stringUtilUWordRep.asm -o stringUtilUWordRep.o -Fhunk
vlink -o stringUtil.lib stringUtilUByteRep.o stringUtilUWordRep.o -bamigahunk -gc-all -gc-empty
This gives no warnings nor errors, and generates a stringUtil.lib file of 232 bytes (ie, 52 bytes smaller than before).

Unfortunately, when I try to link it to my exe, it gives this warning and error:
Code:
execString: vlink -o PrintDecimal2.exe PrintDecimal2.o -L "E:\Amiga\Dev\NDK_3.9\Include\linker_libs" -L "E:\Amiga\Dev\asm\my_linker_objs" -l amiga -l stringUtil -bamigahunk -gc-all -gc-empty
Warning 12: "\Amiga\Dev\asm\my_linker_objs\stringUtil.lib" is already an executable file.
Fatal error 16: E:\Amiga\Dev\asm\my_linker_objs\stringUtil.lib: Section appeared twice in \Amiga\Dev\asm\my_linker_objs\stringUtil.lib.
Aborting.
So is there any way I can tell vlink not to generate an executable, but a lib? A bit like you have -Fhunk and -Fhunkexe in vasm? Anything else I could try?

@ alkis: yeah, I forgot to include my lib source, earlier, silly me. Hopefully I've included everything this time..
Attached Files
File Type: zip PrintDecimal2.zip (3.1 KB, 54 views)
guy lateur is offline  
Old 16 July 2017, 15:33   #47
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
You are on Windows, right?

Open a cmd and go to the folder holding the *.o and try

copy /b UByteRep.o+UWordRep.o foo.lib

And now link with foo.lib
alkis is offline  
Old 16 July 2017, 15:55   #48
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
YES!
That a) works and b) seems to have the desired effect!
Thanks a lot for your time and patience, alkis, you've been a great help!

Current lib size: 364 bytes
UByteRep.o: 160
UByteRep.o: 204
Exe's:
Code:
With UWordRep:
.o:   816
.exe: 784
Without UWordRep:
.o:   788
.exe: 656
The difference in exe sizes is 128 bytes, which can probably not be explained by just commenting out those 2 lines alone. The UWordrep lib is 204 bytes, so there's probably still some overhead going on somewhere, I guess. Hey, not that I'm in any way complaining, of course..
guy lateur is offline  
Old 16 July 2017, 18:44   #49
phx
Natteravn
 
phx's Avatar
 
Join Date: Nov 2009
Location: Herford / Germany
Posts: 2,496
Quote:
Originally Posted by guy lateur View Post
So is there any way I can tell vlink not to generate an executable, but a lib?
The -r option tells vlink to generate another object file and not an executable. Generating a library is usually not the task of a linker.

Fortunately alkis knew a Windows equiavalent for join(AmigaOS) or cat(Unix). I cannot help you very much with Windows details.

BTW, the -M (map file) option of vlink may show you a lot of interesting information about the linking process. So you can more easily decide what happened.
phx is offline  
Old 16 July 2017, 18:56   #50
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Summary: so far, so good!

Alright, time to take a step back and see what we've learned. I've attached the latest version of my code.

It no longer links to amiga.lib, which I'm very happy about, because people kept shouting at me that I really shouldn't be doing that -- and they were/are right. It's including LVOs.i now, which is way more practical and efficient than I thought. For one, it does not incur the 32 kb (ok, to binary) penalty I assumed it would, as it only includes the things that are needed ('dormant code', I believe it's called).

It's now using gmake to build, rather than running some long winded python script. You can also use the make.exe which comes included with vbcc, which I had installed just to use vasm & vlink, but which I didn't realise came with a make.exe included. So @phx: I'm even more sorry to have wasted your time there..

It could still use some work, of course. It still uses macros for the printing code; I'd like that to become a lib, too. It's still not decently documented (*) nor optimised. And the makefiles could probably also be cleaner and more complete (eg, a make clean would be nice).

Anyway, I'm very happy with the progress I've made over the last couple of days. Thank you again to all who have contributed to this!

(*) I'll look into this autodoc thing. Question, though: can I write this lib (in asm) so that it can be used from C code as well? Or does that mainly happen from the C side?
Attached Files
File Type: zip PrintDecimal.zip (11.6 KB, 60 views)
guy lateur is offline  
Old 16 July 2017, 19:33   #51
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by phx View Post
The -r option tells vlink to generate another object file and not an executable. Generating a library is usually not the task of a linker.
Yep, I can confirm that this works even better. Here's the modified makefile:
Code:
asm = vasm
asmopt = -Fhunk -esc

lnk = vlink
lnkopt = -r -bamigahunk -gc-all -gc-empty
lnkin = stringUtilUByteRep.o stringUtilUWordRep.o
lnkout = -o stringUtil.lib

all: stringUtilUByteRep.asm stringUtilUWordRep.asm Makefile
	$(asm) $(asmopt) -o stringUtilUByteRep.o stringUtilUByteRep.asm
	$(asm) $(asmopt) -o stringUtilUWordRep.o stringUtilUWordRep.asm
	
	$(lnk) $(lnkopt) $(lnkin) $(lnkout)
This generates a file of 244 bytes, which is the best we've ever done. Exe sizes remain exactly the same. Excellent!

Quote:
Originally Posted by phx View Post
Fortunately alkis knew a Windows equiavalent for join(AmigaOS) or cat(Unix). I cannot help you very much with Windows details.
Yep, and now I have 2 solutions for doing this on windows. Actually, I'll be updating my system soon, so I might have a look at how this goes on linux, too..

Quote:
Originally Posted by phx View Post
BTW, the -M (map file) option of vlink may show you a lot of interesting information about the linking process. So you can more easily decide what happened.
Thank you, I'll look into that!
guy lateur is offline  
Old 16 July 2017, 19:43   #52
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Nice. Well done.

Add this at the bottom of your Makefile for clean
Code:
clean:
	del *.o PrintDecimal.exe
(Note: It's two lines, it's important to stay two lines)

There three things you need to do to get your lib's functions callable from C.
1) prepend functions names with _ (i.e. _UByteRep) See C compilers prepend symbols automatically with '_', and if you called UByteRep compiler will change it to _UByteRep and then the linker will not find the symbol.

2) get parameters from stack (there is a workarround for that, but lets keep it simple). so every function in your lib should load values from stack.

3) save registers that you use, except a0/a1/d0/d1 (which might give you a hint why choosing say a0 to hold the buffer might be better ;-) )

so say this
Code:
UByteRep:
	divu	#10,d0
	swap	d0
	clr.l	d1
	move.b	d0,d1
	add.b	#48,d1
	move.b	d1,2(a5)
could go something like (I changed a5 to a0, so I don't have to save a5)

Code:
	XDEF	_UByteRep

; arg in d0 (unsigned byte) (is modified)
; result in (a5)
; -- can probably be optimised..
_UByteRep:
	move.l 	4(sp),d0
	move.l  8(sp),a0
	divu	#10,d0
	swap	d0
	clr.l	d1
	move.b	d0,d1
	add.b	#48,d1
	move.b	d1,2(a0)

Also, realistically speaking, the call to LVOWrite isn't something that you want to put in a lib. Even macro is kind of stretching it. In real world senarios, you make the call in your source code. But macro I guess could be ok. Not in a lib.

Lastly, some conventions for the Makefile.
AS is what is generally used to hold the assembler.
ASFLAGS for asm options
LD for the linker
LDFLAGS for the linker options

all: is used when you have defined multiple targets and you pull them all together in all
in your case instead of all should be "PrintDecimal.exe:" (without the quotes)
alkis is offline  
Old 16 July 2017, 19:54   #53
Thorham
Computer Nerd
 
Thorham's Avatar
 
Join Date: Sep 2007
Location: Rotterdam/Netherlands
Age: 47
Posts: 3,751
Quote:
Originally Posted by guy lateur View Post
It's including LVOs.i now, which is way more practical and efficient than I thought. For one, it does not incur the 32 kb (ok, to binary) penalty I assumed it would, as it only includes the things that are needed ('dormant code', I believe it's called).
It's actually better than that. LVOs.i doesn't add any code at all. Ever. For example, this:
Code:
    jsr     _LVOAllocate(a6)
just becomes this:
Code:
    jsr     -186(a6)
Thorham is online now  
Old 16 July 2017, 20:16   #54
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
There three things you need to do to get your lib's functions callable from C.
<snip>
So I won't be trying that then, for now, thank you!

Quote:
Originally Posted by alkis View Post
Also, realistically speaking, the call to LVOWrite isn't something that you want to put in a lib. Even macro is kind of stretching it. In real world senarios, you make the call in your source code.
Really? Because I was trying to make it so that I wouldn't have to have anything LVO-related in my main code. Why is it bad to do that in a lib?

Quote:
Originally Posted by alkis View Post
Lastly, some conventions for the Makefile.
AS is what is generally used to hold the assembler.
ASFLAGS for asm options
LD for the linker
LDFLAGS for the linker options

all: is used when you have defined multiple targets and you pull them all together in all
in your case instead of all should be "PrintDecimal.exe:" (without the quotes)
Ok thanks, that's good to know!
guy lateur is offline  
Old 16 July 2017, 20:19   #55
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by Thorham View Post
It's actually better than that. LVOs.i doesn't add any code at all. Ever. For example, this:
Code:
    jsr     _LVOAllocate(a6)
just becomes this:
Code:
    jsr     -186(a6)
Oh yeah, I see now, I think!
guy lateur is offline  
Old 16 July 2017, 20:32   #56
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by guy lateur View Post
Really? Because I was trying to make it so that I wouldn't have to have anything LVO-related in my main code. Why is it bad to do that in a lib?
Cause there is no point. _LVOWrite needs to load 3 register and call the OS. What exactly would you gain from a subroutine? You can't gain anything. Only lose.
alkis is offline  
Old 16 July 2017, 20:39   #57
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
Cause there is no point. _LVOWrite needs to load 3 register and call the OS. What exactly would you gain from a subroutine? You can't gain anything. Only lose.
I'd hoped to gain the ease of use. What do I lose when doing it from a lib? Doesn't that go through the same 3 registers and OS call?
guy lateur is offline  
Old 16 July 2017, 22:18   #58
matthey
Banned
 
Join Date: Jan 2010
Location: Kansas
Posts: 1,284
Quote:
Originally Posted by guy lateur View Post
It no longer links to amiga.lib, which I'm very happy about, because people kept shouting at me that I really shouldn't be doing that -- and they were/are right. It's including LVOs.i now, which is way more practical and efficient than I thought. For one, it does not incur the 32 kb (ok, to binary) penalty I assumed it would, as it only includes the things that are needed ('dormant code', I believe it's called).
Be careful. Some of these old school assembler programmers are very set in their ways. Some of what they know and use is from what they first learned and using a very minimalist Amiga. I use a linker and even link with the amiga.lib. It is probably slower (to assemble and link) but any hardware later than 1990 probably won't notice the difference. It is convenient as it can save a little time typing.

Code:
   INCLUDE "exec/macros.i"

   ...
   JSRLIB OpenLibrary
vs

Code:
   INCLUDE "LVOs.i"

   ...
   jsr (_LVOOpenLibrary,a6)
The resulting executable is equally as efficient. It really comes down to preference once you have better than snail hardware.

Quote:
Originally Posted by guy lateur View Post
I'd hoped to gain the ease of use. What do I lose when doing it from a lib? Doesn't that go through the same 3 registers and OS call?
You would be calling a function in the lib which calls an OS library function when just calling the OS library function would suffice. A function is called with a bsr or jsr and end with a rts. The bsr and jsr write a return address to the stack and jump to a different PC (Program Counter) location in memory where program execution continues. The rts removes the return address from the stack and jumps to it. Then there is the issue of passing arguments which may need to be moved or placed on the stack to comply with standards/conventions. Using a function is fairly slow, especially on these old processors. The C language will inline functions for you (fold small functions into other functions removing the bsr/jsr and rts) but assembler is all manual control. It is faster to write longer functions or inline code usually with macros (too much macro use can be difficult to read though). Reusing functions, including short functions, allows for smaller code and better use of caches though. Smaller code and more efficient cache use is faster also so best performance is finding a good balance between reusing code and inlining code. Efficient hardware should make function calling as cheap as possible but the 68k was a little before CPUs made function calling as efficient as possible so best performance is going to be more inlining and fewer function calls.

Last edited by matthey; 17 July 2017 at 12:51.
matthey is offline  
Old 17 July 2017, 01:26   #59
alkis
Registered User
 
Join Date: Dec 2010
Location: Athens/Greece
Age: 53
Posts: 719
Quote:
Originally Posted by guy lateur View Post
I'd hoped to gain the ease of use.
How? Show me
alkis is offline  
Old 17 July 2017, 09:21   #60
guy lateur
Registered User
 
guy lateur's Avatar
 
Join Date: May 2017
Location: Belgium
Age: 50
Posts: 334
Quote:
Originally Posted by alkis View Post
How? Show me
Ok ok, I think matthey drove this one home already.

Darn, and I was so happy with my new lib..
guy lateur 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
AmiDevCpp and Floats AmigaEd Coders. General 0 18 January 2006 03:16

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 18:59.

Top

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