flat assembler
Message board for the users of flat assembler.
![]() Goto page Previous 1, 2, 3, 4 |
Author |
|
vid 24 Oct 2005, 10:00
Reverend:
1. of course don't push everything always. "preserve" means leave unchanged. 3. string i want are compatible with zero-terminated strings, they just only carry more information with them, like Code: struct string value*,bufsz { local ..sz ;size of string if bufsz eq .#.max dd ..sz else .#.buffersize dd bufsz end if .#.sz dd ..sz . db value if value eqtype "" ;auto-add ending 0 for string constants db 0 end if ..sz = $-. } _txt string 'Hello World' _capt string 'Message' invoke MessageBox,0,_txt,_capt,0 |
|||
![]() |
|
vid 25 Oct 2005, 16:13
on second thought (
![]() altough it makes it harder when working with strings directly, it contains lot of useful code, and also rewriting whole Fresh or having another string library for Fresh wouldn't be very nice. and it fixes many common problems, mainly resizing string. it's already written, tested, quite independent (it only requires heap funcs) , so i definitively vote for it. Problem comes out with naming (again and again), i think i'd be fine to keep fresh/windoze way (MemAlloc, StrCat), so Fresh doesn't have to be changed too much to use the library. Maybe we can add name-prefix separator (as Reverend suggested), like "Str.Len", "Mem.Alloc" (i used to use this way too) but it would require changing all names for Fresh to use the library. Without adding separator, problem comes with names like "HeapAlloc", eg. which are already name of win32 imports. Maybe "MemHeapAlloc?" PS: Sorry about reopening name issue again ![]() ![]() |
|||
![]() |
|
decard 25 Oct 2005, 17:17
I was about to suggest Fresh StrLib. Thanks vid
![]() |
|||
![]() |
|
vid 25 Oct 2005, 17:37
how about the names? Do you think names like StrLen, MemAlloccan can work out (altough they make problems with things like HeapAlloc)?
|
|||
![]() |
|
SDragon 26 Oct 2005, 02:02
vid, you can get rid of buffersize field, if you will allocate memory in the chunks of constant size.
For example, buffersize is always string length rounded up to 256 bytes: Code: string length buffersize <= 256 256 from 257 to 512 512 from 513 to 768 768 from 769 to 1024 1024 etc. In this case, buffer size can be easily calculated as Code: MOV eax, dword[strptr-4] ADD eax, 255 AND eax, -256 ; eax now contains buffersize Checking for buffer overflow and increasing buffer is very fast and short too. This idea can be generalized, so you can make buffersize some function of string length (say, round it to the nearest power of 2). By the way, a lot of Win32 API returns the number of characters copied to the buffer, so converting from null-terminated Win32 strings to FASM strings seems to be an easy task. Just wrap Win32 functions such as GetWindowText in your own macros returning FASM strings: Code: macro myGetWindowText hwnd, str { ; Get buffersize. ; Can be replaced with "mov eax, dword[str-8]" if you don't like ; the idea of constant size chunks. mov eax, dword[str-4] add eax, 255 and eax, -256 ; Call the function push eax push str push hwnd call GetWindowText ; Save string size mov dword[str-4], eax } There are a lot of such functions, but wrapping is routine and trivial. May be, it could be done with FASM macros? |
|||
![]() |
|
vid 26 Oct 2005, 04:04
nice idea
but somebody would have to write code... i think this is a little better than Fresh's library, it doesn't have to reallocate memory after each byte added to string. |
|||
![]() |
|
Kain 26 Oct 2005, 06:08
Some good iteas, but I like the maxlength field to be in the record, somewhere.
To have a general purpose, multi-platform library, you will need a memory manager. It would be a good idea to tie in 'string' memory with the general memory. Example, you allocate a 'string' of 300 bytes, the string allocation function calls the general memory function, and adds it's own fields to it. gen. memory record: next_chunk prev_chunk next_segment prev_segment size (offset -4 for general memory, acts as string_maxlength at offset - ![]() ends. start of string record: string_length (offset -4) data (offset 0) zero-termination ends. The memory manager would allocate heap memory from the system in 64k segments (or requested amount to nearest 64k), then break the segments up into chunks as needed. All library routines that use buffers and strings would naturally have to use the library memory manager. It's higher overhead, but that's the price to pay for having code that compiles under multiple OSes. You'll have 2 allocation and 2 freeing functions: malloc - allocates memory for general memory free - frees allocated memory stralloc - allocates memory for general memory + string memory strfree - frees string memory Or if one prefers (such as me); mem.alloc, mem.free, str.alloc, str.free Or, without dots; mem_alloc, mem_free, str_alloc, str_free |
|||
![]() |
|
vid 26 Oct 2005, 08:20
for example win32 already has memory manager, no need to write ours. i was thinking about:
mem.alloc ;for global memory mem.free mem.resize heap.init ;create heap heap.alloc ;and for heap heap.free heap.resize and then for heap use system if possible, and make own manager for OSes where it isn't supported. btw. i am already writing this code for win32 (only a wrapper of system calls) |
|||
![]() |
|
Reverend 26 Oct 2005, 19:02
vid: OK, I agree to what you all came to. mem.alloc, mem.free, etc... I will soon upload some of my procs.
|
|||
![]() |
|
Posetf 29 Oct 2005, 11:09
SDragon wrote:
Nice try, but a tad too simple. If you allocate a buffer of 1024, then get 35 characters of text back, from that point until the end of time you will think the buffer is only 256 bytes. It may also cause a memory leak, though I believe most memory managers work from memory address rather than addr&len. |
|||
![]() |
|
SDragon 31 Oct 2005, 10:58
OK, buffersize should be in the string for memory management purposes.
[quote]If you allocate a buffer of 1024, then get 35 characters of text back, from that point until the end of time you will think the buffer is only 256 bytes.[\quote] There is no memory leak if you use HeapAlloc/Free or other memory manager that stores buffer size in its own structures. You will think the buffer is 256 bytes. Then you get, for example, another 1000 characters in the buffer. The algorithm says you need reallocation, and you realloc() the buffer to 1024 bytes. No problems here, just one unnecessary call to realloc(), but it's tolerable. Although, I agree with Kain: Storing buffer size in the string would be a better solution. |
|||
![]() |
|
vid 02 Nov 2005, 11:02
i decided to use Fresh's string library anyway. it's a bit harder to work with string directly, but it is already written and tested, and already used in fresh. i've already started rewriting it.
[EDIT]Reverend: please wait until i post here my version so we can consilidate style a bit.[/EDIT] |
|||
![]() |
|
Goto page Previous 1, 2, 3, 4 < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2023, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.