flat assembler
Message board for the users of flat assembler.

Index > High Level Languages > Standard Library for FASM?

Goto page Previous  1, 2, 3, 4  Next
Author
Thread Post new topic Reply to topic
mrpink



Joined: 03 Jun 2005
Posts: 27
Location: Germany
mrpink 18 Oct 2005, 14:38
Maybe it would be a good idea to compile a list of most of the functions that should be
part of the library and a comment associated with each that describes what the function does,
its parameters, its return value(s), the status of the registers, the pre- and postconditions
of the function and so on.
The comments should be like those used in java such that the documentation of the
library can be generated automatically from the source.
Then everybody can pick one or more of them and implement them.
Post 18 Oct 2005, 14:38
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 18 Oct 2005, 15:10
Quote:
So let's use standard FASM macro library + globals.inc from Fresh. Then library could be compiled with both FASM and Fresh libraries.
agree

btw, how about system abstraction layer? (like system.inc of FASM). I mean some common things like memory allocation, exit process, get program arguments etc. for example memory allocation is thing which is required almost everywhere and you cannot start writing some routines (for exmaple string library) without it. i mean something like this in windoze:
Code:
format PE
include '%fasmlib%\win32\memory.inc'
include '%fasmlib%\string.inc'
    

and under linux:
Code:
format ELF
include '%fasmlib%\linux\memory.inc'
include '%fasmlib%\string.inc'
    

memory.inc will conatain some "malloc", which will be called by "string.inc" to allocate memory.
Post 18 Oct 2005, 15:10
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 18 Oct 2005, 15:21
on second thought, there are so few needed system thingies we can place them in single file, like "%fasmlib%/win32.inc". directory "%fasmlib%/win32/" will be for win32-specific includes (like direct X, win32 port of opengl etc.)
Post 18 Oct 2005, 15:21
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 18 Oct 2005, 16:07
well, on third thought there will be quite a bunch of them. For me the best idea seems to be this: "%fasmlib%/win32.inc" will contain things that will be required for system-independent routines to run (like memory allocation for "%fasmlib%/string.inc"), and "%fasmlib%/win32/" directory will contain additional things for that system (like "%fasmlib%/DOS/console.inc", "%fasmlib%/win32/console.inc" etc.). Remember that we must remain to be able to compile executable for any OS under any other OS.

In attachment is a example how i imagine it (i think it can't get any simpler than in here)

[edit] attachment deleted - there's newer one few posts below [/edit]


Last edited by vid on 18 Oct 2005, 22:20; edited 1 time in total
Post 18 Oct 2005, 16:07
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 18 Oct 2005, 17:51
1. In one of my projects I used such solution:
Code:
macro osscall name*, [arg]
 { common
    if ~ arg eq
   reverse
    push arg
   common
    end if
   match =WIN32, OS \{ call win_ # name \}
   match =LINUX, OS \{ call lin_ # name \} }    
I had to define the constant 'OS equ WIN32' or 'OS equ LINUX', and it called apriopriate functions. Like this:
Code:
OS equ WIN32
osscall read, 1, 2, 3
; generated output: 
; push 3
; push 2
; push 1
; call win_read

; other file

OS equ LINUX
osscall read, 1, 2, 3
; generated output: 
; push 3
; push 2
; push 1
; call lin_read
    
Specifying the constant OS should be as normal as selecting 'format PE GUI' or 'format ELF' (or whatever).

2. Why should I preserve ecx and edx? I suggest the solution as in windows -> eax, ecx and edx can be changed everytime and don't have to be preserved.

3. Declaring data as eg. 'itoa.digits' is a great idea. Let's stick to it.
Post 18 Oct 2005, 17:51
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 18 Oct 2005, 18:16
1. for my taste it's too much overhead. Porting application is worth of retyping few lines. Also we don't need to be TOO general, i'd rather leave it simpler (eg. not calling encapsulated OS, but calling procs from our library - matter of view).

2. library will be used by asm code. i don't want to push/pop registers each time i need to call something from library. 3 GPR registers i have left for general purpose (!) usage just aren't enough

new version in attachment. example of fileio system routines (%fasmlib%/win32/fileio.inc). I also used globals.inc from FRESH there (with strconstants removed, they should be rewritten anyway using struc's new "." feature)


Description:
Download
Filename: fasmlib_example.zip
Filesize: 4.65 KB
Downloaded: 795 Time(s)

Post 18 Oct 2005, 18:16
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
decard



Joined: 11 Sep 2003
Posts: 1092
Location: Poland
decard 18 Oct 2005, 18:49
1. Again I agree with vid. It seems to be simpler for me.

2. I guess we need another poll Wink Personally I prefer not saving eax ecx and edx.... but you have to agree quickly, or project will be dropped again.
Post 18 Oct 2005, 18:49
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 18 Oct 2005, 19:47
2. why the hell? push ecx edx and pop edx ecx isn't that much, and how many times will you need to save it outside procedure? Are 3 GPRs enough. It's just stupid drawback from MS fastcall convention. I don't see ANY advantage of this
Post 18 Oct 2005, 19:47
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 18 Oct 2005, 20:00
vid wrote:
library will be used by asm code
I'd say not necessarily. I'd like to use such library in my C programs too. If we use registers for passing arguments I will have to use some overhead procedures like this:
Code:
proc    _some_proc arg1, arg2
        mov     eax, [arg1]
        mov     edx, [arg2]
        call    some_proc
        ret
endp    
Or I'll have to use inline asm.
I'd rather avoid both.
Post 18 Oct 2005, 20:00
View user's profile Send private message Visit poster's website Reply with quote
decard



Joined: 11 Sep 2003
Posts: 1092
Location: Poland
decard 18 Oct 2005, 20:20
vid wrote:
2. why the hell? push ecx edx and pop edx ecx isn't that much, and how many times will you need to save it outside procedure? Are 3 GPRs enough. It's just stupid drawback from MS fastcall convention. I don't see ANY advantage of this


At least it won't be confusing. Now, for example, when I work with Fresh source (most routines from Fresh library are preserving all registers they use), sometimes I don't know if given function will trash EAX or not. Some functions return something in this register, while others are preserving it. So I have to remember all that mess. It ends up that I usually assume that EAX is always destroyed. I'm planning to clean this up, most likely all functions won't save EAX, ECX and EDX.
Post 18 Oct 2005, 20:20
View user's profile Send private message Visit poster's website Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 18 Oct 2005, 20:42
rather clean it up so that all funcs either return something in EAX, or trash it if they report error, and all funcs preserve ECX and EDX. There won't be nothing to confuse if all fasmlib's functions will preserve ECX and EDX, and not preserve EAX. I still don't see ANY advantage of trahing ECX and EDX and leaving us with only 3 GPRs. Why shouldn't we stop stupid MS's lazyness with implementing fastcall?

Reverend: about usage in HLLs - there is better library in each HLL, that you can use. I don't want to make FASMLIB worser just to make it runable in HLLs.

4. Also for now i found carry flag the best way to report error. Only it's disadvantage is it can't be used from HLL. For anything else it's better, it easier to set (see further) than anything else and easier to check than anything else. Another advantage is that you have unified error reporting system, which is quite impossible with reserving one return value as error (see win32api mess with some procs returning 0 and some -1 on error).

Here is my template for proc
Code:
proc <name> <args>
  <locals>
  push <all regs it modifies exc. eax>

  <code>

.rnc:
  clc
  jmp .r
.rc:
  stc
.r:
  pop <regs it pushed>
  ret
endp    

so inside code it's just "jmp .rc" or "jmp .rnc" instead of setting value of eax + you can use just "jmp .r" if you already have return value in CF, which eases going few levels up on error.
Really, only dis
Post 18 Oct 2005, 20:42
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Kain



Joined: 26 Oct 2003
Posts: 108
Kain 19 Oct 2005, 01:09
Here are a few of ideas adopted from the HLA standard library which is a joy to use:

1. preserve all registers used, including FLAGS, unless used for returns.
-disadvantage: a little more overhead
-advantage: assembly programmer won't have to worry about anything changing between routine calls.

To save on recursive algorithms, call a 'shell' procedure which preserves once then calls the recursive function which doesn't preserve.

2. namespaces to group all like functions.
For example, itoa above would be called by str.itoa ..., or 'malloc' would be mem.alloc

3. have a standard 'string' so that a string pointer can be passed to a routine such as 'itoa' instead of a buffer. The string pointer would also have a 'maxlength' which would allow checking for buffer overflow.

A good z-string compatible format usen by HLA is:

maxlength dword
length dword
character data ...
0 termination

Even if a string format like this is not to be used, it is still advisable to at least have a general 'memory' pointer to pass to functions that use buffers.
Post 19 Oct 2005, 01:09
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 19 Oct 2005, 08:15
1. hmm... including flags? interesting idea, but will that have any real usage? i can't think of one.

2. It was in original idea... but it is useless for very common things, where everyone is used to some name, and nobody would use that name for his stuff. and how about macros, do you like "globals.idata"?

3. i think we definitevely need null-terminated string, maybe with length at [str_pointer-4] which keeps it compatible with normal null-terminated strings. i don't know about maxlength, it may be good idea.
Post 19 Oct 2005, 08:15
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Kain



Joined: 26 Oct 2003
Posts: 108
Kain 19 Oct 2005, 21:49
1. It has only rare uses. Doing so would fit into a philosophy of a library that returns without changing the state of the computer beyond what is necessary. It is not truly needed.

2. I think it would still help to distinguish the fasmlib functions at a glance. As I like things to be neat, tidy and grouped together, the 'globals.idata' idea fits in well with me.

3. it all depends on how much error checking you want in the library. Having a maxlength field allows for checking buffer overflows, without which you would need an extra buffer_length argument to be passed like in Windows API. Having neither is not good IMO.
Post 19 Oct 2005, 21:49
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 19 Oct 2005, 22:00
1.agree
2.it doesn't look good in code. Being too general isn't always good. You must think if that generality brings some effort, and long names for these things just doesn't!
3. it also depends on how fine do you want string usage to be. Ever used strings in pascal style and in C style? C's was hell because of lack of maximum length / reallocating. funcs worked with buffer whose size was unknown to them.
Post 19 Oct 2005, 22:00
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 20 Oct 2005, 19:57
1. "agree" hmm... but yo agreed to preserving flags or to sentence "It is not truly needed"? Smile Imo, flags preserving is not what we really need.
About all-registers-used-preserving, I agree now. I see your point and it really convinced me.

2. We can do both. Let's use in fasmlib longer names 'mem.alloc' etc. but define also 'label malloc at mem.alloc' (it's great fasm ability to hace two labels pointing at the same address) for usage in our programs.

3. If we would like to have some pascal-style-strings, it's length should be of word size. byte (2^Cool is not wnough and dword (2^32 is too big and no string will ever have a half of it). Even 2^16 (word size) is very much for a string -> it's 64 kB of text
Post 20 Oct 2005, 19:57
View user's profile Send private message Visit poster's website Reply with quote
Kain



Joined: 26 Oct 2003
Posts: 108
Kain 20 Oct 2005, 23:20
1. we agreed on not preserving flags, but preserving all used registers.

2. using unions would work, but may introduce some confusion, especially to beginners looking at example sources.

3. I wouldn't bet on it! I've loaded strings with over 1 mega of characters for easy parsing/modifying using string library routines... not the best "assembly" style of programming, but sometimes, I just don't want to spend too much time on a small single-purpose utility, or knock out a quick demo for later refining.
Post 20 Oct 2005, 23:20
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7105
Location: Slovakia
vid 21 Oct 2005, 10:12
well, as i see it:
1 - preserve all regs exc. EAX always (to prevent confusion decard mentioned and to have 5 usuable GRPs at the same time),
2 - Let's leave it on author of that part of library, you can look up where too much standardization leads. names can be easily changed later...
3 - kain is right, and using words also gives align-issue, and it's a little harder to work with words in 32bit enviroment.

First of all we should start writing something instead of talking Smile
Post 21 Oct 2005, 10:12
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
Reverend



Joined: 24 Aug 2004
Posts: 408
Location: Poland
Reverend 21 Oct 2005, 17:15
vid wrote:
1 - preserve all regs exc. EAX always
I don't get it. Do you mean I should push/pop registers even when they're unused?

2 - ok
3 - in fact I think C-style strings are better. See that win32 and linux (at least I think linux does) uses c-style strings. If we wanted to use our procs we will always have to convert between string styles. Let's use the one which is most common ie. C-style.
Post 21 Oct 2005, 17:15
View user's profile Send private message Visit poster's website Reply with quote
Kain



Joined: 26 Oct 2003
Posts: 108
Kain 22 Oct 2005, 00:46
Let's try to summarize this and move on to something else.

1. Preserving Registers:

FLAGS: no
EAX: no
All else: preserve if used. If routine calls Windows API, preserve accordig to Intel ABI (I think Linux does this too?); Windows thrashes EAX, ECX, EDX, so always preserve ECX and EDX when calling Windows API.

2. Naming according to author discretion. Try to keep to standards and short.

3. Some string conversion is inevitable with string structures, but functions will be much faster if this information is readily available. The zero-termination makes structured strings compatible with C-style strings.

string structure:
max_length @ -8
current_length @ -4
character_data @ 0
zero termination byte @ character_data + current_length
padding: dword alignment

string functions take pointer to character data address.

==================================================

Hopefully everyone can agree to some level on these.

The most important hurdle to cross is the memory manager. For example, what to have in the structure? Will strings be managed by the memory manager or will they have a separate manager... since already the smallest string will be at least 12 bytes, adding more bytes via a general memory handler would probably double the minimum string size.
Post 22 Oct 2005, 00:46
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  
Goto page Previous  1, 2, 3, 4  Next

< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.