flat assembler
Message board for the users of flat assembler.

Index > Main > Is it possible to get the file size of a file at compilation

Author
Thread Post new topic Reply to topic
scippie



Joined: 26 Jan 2017
Posts: 11
scippie 26 Jan 2017, 19:48
I like to use FASM for my own OS development. Not only do I like how it reminds me of assembler when I was 14 years old when I was coding my first OS in Turbo Assembler, but it also has lots of cool features.

For example, to boot my OS, I create a floppy disk image. I don't need special tools for this, because with the file command, I can just combine different files and with the rb command, I can put them in exact places.

So I first compile all my .asm's and then I join all their binaries by compiling disk.asm which is actually a lot of data definitions and bin-file references.

I am now creating a complete FAT12 structure within that file and it works perfectly. The only problem I have is that in a FAT12 structure, I need to have an exact file size to put in there (at this point, I just always read enough from the disk).

So, like there is a file command, is there something like a filesize function or is there a workaround for this? Or can it maybe be added? It would be so cool to be able to create a complete correct disk image just by compiling my disk.asm file.

I could of course create a script that creates a small .inc file for every .bin file I have, just containing dd <filesize>, but that would become such a mess when the number of files grows.
Post 26 Jan 2017, 19:48
View user's profile Send private message Reply with quote
scippie



Joined: 26 Jan 2017
Posts: 11
scippie 26 Jan 2017, 19:59
I already just thought of a better way, but I'd still prefer a function if there were any.

I just did this:

FOO:
file 'foo.bin'
FOO_end:

and in my FAT12 header:
dw (FOO / 512 - 33 + 2)
dd (FOO_end - FOO)

(I still need to add some constants Smile )
Post 26 Jan 2017, 19:59
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 26 Jan 2017, 20:01
If you use FILE directive to include contents of entire file, you can simply compute the difference in offsets to get the size of that file:
Code:
example file 'example.bin'
example_size = $ - example    
And since fasm allows forward-referencing, you can use the value of "example_size" in your headers (before the actual files are included) and fasm is going to resolve these variables so that headers end up containing correct values.

If you do not include entire file anywhere, you can still use the same trick to compute the file size, just use the VIRTUAL block to avoid placing a whole file in the output:
Code:
virtual at 0
    file "example.bin"
    example_size = $
end virtual    

The above examples apply to both fasm 1 and fasmg with no difference. But in case of fasmg you can also do some trickier things, like loading the contents of a file into a string:
Code:
; WARNING: this snippet works with fasmg only
virtual at 0
    file 'example.bin'
    load example_string : $ from 0
end virtual

dd lengthof example_string      ; size of file
db example_string               ; contents of file    
Post 26 Jan 2017, 20:01
View user's profile Send private message Visit poster's website Reply with quote
scippie



Joined: 26 Jan 2017
Posts: 11
scippie 26 Jan 2017, 20:57
Tomasz Grysztar wrote:
If you use FILE directive to include contents of entire file, you can simply compute the difference in offsets to get the size of that file:
Code:
example file 'example.bin'
example_size = $ - example    

That's even better! Thanks!

Tomasz Grysztar wrote:
The above examples apply to both fasm 1 and fasmg with no difference. But in case of fasmg you can also do some trickier things, like loading the contents of a file into a string:
Code:
; WARNING: this snippet works with fasmg only
virtual at 0
    file 'example.bin'
    load example_string : $ from 0
end virtual

dd lengthof example_string      ; size of file
db example_string               ; contents of file    

Cool stuff. Fasm is great Smile
Post 26 Jan 2017, 20:57
View user's profile Send private message Reply with quote
scippie



Joined: 26 Jan 2017
Posts: 11
scippie 26 Jan 2017, 21:22
So, after reading your text, I wonder if it's possible to have the length of a text string as first byte before the string. Something like:

label db <len>,'Hello world!'
How could <len> be automated?
Post 26 Jan 2017, 21:22
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 26 Jan 2017, 21:27
With fasmg it can be as simple as:
Code:
struc str value
        . db lengthof value, value
end struc

hello str 'Hello world!'    
With fasm 1 it requires a little bit more work:
Code:
struc str value
{
        local ..length
        . db ..length,value
        ..length = $ - (.+1)
}

hello str 'Hello world!'    
Post 26 Jan 2017, 21:27
View user's profile Send private message Visit poster's website Reply with quote
scippie



Joined: 26 Jan 2017
Posts: 11
scippie 26 Jan 2017, 22:22
Wow, thanks! As I am using fasm 1, it's the struc.

I had to create an extra struc for strings ending with CR/LF, because the struc wouldn't recognize the extra 13,10 after str as extra data in the string.

Or is there a way to make it work with the same struc? I searched the manual for this (it has been very long since I looked at the manual) but couldn't find it.
Post 26 Jan 2017, 22:22
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 26 Jan 2017, 22:34
scippie
You can put an ampersand directly after the argument name in the first line. This will tell fasm to use the whole remainder of an argument line as the last argument. Aside from that passing arguments surrounded by < and > allows to ignore commata as argument separators.

_________________
Faith is a superposition of knowledge and fallacy
Post 26 Jan 2017, 22:34
View user's profile Send private message Reply with quote
scippie



Joined: 26 Jan 2017
Posts: 11
scippie 26 Jan 2017, 23:23
l_inc wrote:
scippie
You can put an ampersand directly after the argument name in the first line. This will tell fasm to use the whole remainder of an argument line as the last argument. Aside from that passing arguments surrounded by < and > allows to ignore commata as argument separators.

Thanks! That's perfect.

Is it documented? I didn't see it in the docs, but I'm a terrible reader.

Thanks for all the quick help guys. I feel welcome already!
Post 26 Jan 2017, 23:23
View user's profile Send private message Reply with quote
l_inc



Joined: 23 Oct 2009
Posts: 881
l_inc 26 Jan 2017, 23:38
scippie
Yes, it's mentioned in the chapter 2.3.3 Macroinstructions. The manual is quite concise about many things. So they are admittedly easy to miss and sometimes hard to understand.

_________________
Faith is a superposition of knowledge and fallacy
Post 26 Jan 2017, 23:38
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< 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-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.