flat assembler
Message board for the users of flat assembler.

Index > Compiler Internals > Having problems with "section '.bss' readable writeable

Author
Thread Post new topic Reply to topic
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 04 Nov 2006, 16:15
In previous versions of fasmw, the "section '.bss' readable writeable" would just reserve data to be allocated at run time. But, with the latest version of fasmw it seems to act just like "section '.data' readable writeable" leaving the data in the code and bloating the size of it. Thomasz (or anyone?), can you fix this.
madmatt
Post 04 Nov 2006, 16:15
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4623
Location: Argentina
LocoDelAssembly 04 Nov 2006, 16:48
Maybe you defined some data instead of reserving space?
Post 04 Nov 2006, 16:48
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8428
Location: Kraków, Poland
Tomasz Grysztar 04 Nov 2006, 17:09
That's the most probable reason. The name of the section doesn't matter - as long as you put only the data reservation directives in it (or, at least, at the end of it), that space is not allocated within the output file.
Post 04 Nov 2006, 17:09
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 04 Nov 2006, 19:23
I've done it the same as I have done it before without problems until now. Another thought, it may be working right and I'm reserving too much data? What is the data limit for the '.bss" section? Below is what I'm trying to reserve.

Code:
  d3d9Textures IDirect3DTexture9 ;pointers to texture objects
               dd MAXTEXTURES dup(?) ;MAXTEXTURES = 2048

  d3d9Surfaces IDirect3DSurface9 ;pointers to surface objects
               dd MAXD3DSURFACES dup(?) ;MAXD3DSURFACES = 256

  d3d9primitive CustomVertex
                db 2048 * (sizeof.CustomVertex * 5) dup(?) ; sizeof.CustomVertex = 20

  d3d9texture  CustomVertexUV
               db 2048 * (sizeof.CustomVertexUV * 5) dup(?) ;sizeof.CustomVertexUV = 28

  ddsurfaces SURFACES
             db sizeof.SURFACES * MAXSURFACES dup(?) ; DDMAXSURFACES = 2048

  soundfx pcmsoundtype
          db MAXSOUNDS*sizeof.pcmsoundtype dup(?) ;MAXSOUNDS = 2048

  chfilename db MAX_PATH dup(?)

  debugtxt db 256 dup(?)

  palette PALETTEENTRY ;main palette
          db sizeof.PALETTEENTRY*255 dup(?)

  workpal PALETTEENTRY ;working palette for color rotations
          db sizeof.PALETTEENTRY*255 dup(?)

  scanlinetable  dd 2050 dup(?) ;can draw up to a screen size of 2048 scanlines
  dscanlinetable dd 2050 dup(?)
  temp768        db 768 dup(?)
  ftoaenv:       times 28 db ?
    
Post 04 Nov 2006, 19:23
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8428
Location: Kraków, Poland
Tomasz Grysztar 05 Nov 2006, 01:24
Check out whether any of your structures (like IDIrect3DTexture9 etc.) doesn't contain any initialized data. As I said, that is the only possible reason I'm aware of that may cause the section data to be put into file.
Post 05 Nov 2006, 01:24
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 05 Nov 2006, 10:07
I've narrowed the problem to the two definitions below:
Code:
  d3d9primitive CustomVertex
                db 2048 * (sizeof.CustomVertex * 5) dup(?)

  d3d9texture CustomVertexUV
              db 2048 * (sizeof.CustomVertexUV * 5) dup(?)
    


I've checked the two structures above and they WERE defining data, I did fix them, but that did not solve the problem. Crying or Very sad
Maybe there is a 64KB (65535 bytes) limit on the data that can be reserved?
If so, I'll just go ahead and use manual allocation of memory.
Post 05 Nov 2006, 10:07
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8428
Location: Kraków, Poland
Tomasz Grysztar 05 Nov 2006, 12:30
There are not limits of any kind or anything like that. Please post some complete code, from your small samples the reason remains invisible.
Post 05 Nov 2006, 12:30
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 05 Nov 2006, 16:46
Here is how I have it set up, before and after the .bss section:

Code:
section '.data' data readable writeable
        include 'Utilities\Utilities_VARIABLES.inc'
        include 'DirectDraw\DirectDraw_VARIABLES.inc'
        include 'DirectVideo\DirectVideo_VARIABLES.inc'
        include 'D2D9\D2D9_VARIABLES.INC'
        include 'DirectInput\DirectInput_VARIABLES.inc'
        include 'DirectSound\DirectSound_VARIABLES.inc'

section '.bss' readable writeable
  d3d9Textures IDirect3DTexture9 ;pointers to texture objects
               dd MAXTEXTURES dup(?)

  d3d9Surfaces IDirect3DSurface9 ;pointers to surface objects
               dd MAXD3DSURFACES dup(?)

  d3d9primitive CustomVertex
                db 2048 * (sizeof.CustomVertex * 5) dup(?)

  d3d9texture CustomVertexUV
              db 2048 * (sizeof.CustomVertexUV * 5) dup(?)

  ddsurfaces SURFACES
             db sizeof.SURFACES * MAXSURFACES dup(?)

  soundfx pcmsoundtype
          db MAXSOUNDS*sizeof.pcmsoundtype dup(?)

  chfilename db MAX_PATH dup(?)

  debugtxt db 256 dup(?)

  palette PALETTEENTRY ;main palette
          db sizeof.PALETTEENTRY*255 dup(?)

  workpal PALETTEENTRY ;working palette for color rotations
          db sizeof.PALETTEENTRY*255 dup(?)

  scanlinetable  dd 2050 dup(?) ;can draw up to a screen size of 2048 scanlines
  dscanlinetable dd 2050 dup(?)
  temp768        db 768 dup(?)
  ftoaenv:       times 28 db ?

; *** A L L   C O D E   L I B R A R Y   C O M P O N E N T S **
section '.code' code readable executable
     proc DllOk  hinst, Reason, Reserved
          .if     [Reason] = DLL_PROCESS_ATTACH
                  call    CpuProcessorInfo
                  call    RndMakeSeed
                  return  TRUE
          .elseif [Reason] = DLL_PROCESS_DETACH
                  ;shutdown stuff here
                  return  TRUE
          .endif
          return  FALSE
     endp     


and the structures:
Code:
MAXTEXTURES equ 2048
MAXD3DSURFACES equ 256

struct CustomVertex ;non-textured drawing
       x       dd ?
       y       dd ?
       z       dd ?
       rhw     dd ?
       diffuse dd ?
ends

struct CustomVertexUV ;textured (sprite) drawing
       x       dd ?
       y       dd ?
       z       dd ?
       rhw     dd ?
       diffuse dd ?
       u       dd ?
       v       dd ?
ends    


Again, I comment the two defines below, and everything compiles to 100kb, I uncomment the two defines below, and the code becomes 500kb:
Code:
  d3d9primitive CustomVertex
                db 2048 * (sizeof.CustomVertex * 5) dup(?)

  d3d9texture CustomVertexUV
              db 2048 * (sizeof.CustomVertexUV * 5) dup(?)
    
Post 05 Nov 2006, 16:46
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8428
Location: Kraków, Poland
Tomasz Grysztar 05 Nov 2006, 16:49
Can you provide also the definitions of structures like IDirect3DTexture9 etc. that you use? They're not in the standard set of includes.

The best would be if you provided the whole set of headers that you use.
Post 05 Nov 2006, 16:49
View user's profile Send private message Visit poster's website Reply with quote
madmatt



Joined: 07 Oct 2003
Posts: 1045
Location: Michigan, USA
madmatt 05 Nov 2006, 17:01
Embarassed Embarassed Embarassed You guys were right after all, I checked my OTHER structures and they were defining data, so I fixed them and everything is working good again, Cool Even us old dog programmers make stupid mistakes from time to time! Very Happy and then broadcast it on a great forum like this Laughing
Post 05 Nov 2006, 17:01
View user's profile Send private message Reply with quote
rhyde



Joined: 03 May 2007
Posts: 21
rhyde 03 May 2007, 17:11
Tomasz Grysztar wrote:
That's the most probable reason. The name of the section doesn't matter - as long as you put only the data reservation directives in it (or, at least, at the end of it), that space is not allocated within the output file.


I've been having some linker issues lately (MSLINK and POLINK) that are related to this problem. In particular, FASM, in some cases, seems to be setting *both* the "initialized data" and "uninitialized data" COFF flags. This generates warnings by the linker when combined with sections that don't have both flags set (and it seems unusual to have both flags set in a section).

I'd also recommend adding a new section type, bss (like 'code' and 'data') that would cause the assembler to generate a warning or error message if the program contains any data-defining directives in the section. This would help avoid questions like this thread's parent.
Cheers,
Randy Hyde
Post 03 May 2007, 17:11
View user's profile Send private message Reply with quote
rhyde



Joined: 03 May 2007
Posts: 21
rhyde 03 May 2007, 17:33
rhyde wrote:

I'd also recommend adding a new section type, bss (like 'code' and 'data') that would cause the assembler to generate a warning or error message if the program contains any data-defining directives in the section. This would help avoid questions like this thread's parent.


I guess I forgot the justification for such a change. I've run into a problem when I have a section generated that has zero length (because it's program generated, largely to pass along segment ordering to the linker). FASM sees no data in the section and automatically attaches a "Uninitialized Data" flag to the guy. If I've put the 'data' flag on it, I wind up with a COFF flags value of something like XXXXXX80. When a second section declaration comes along that *does* have data associated with it, the two get OR'd together producing XXXXXXC0. When I link this against library code, that typically has an XXXXXX80 or XXXXXX40 flag value, the linker issues a warning.

It would be *really* nice to be able to say "data sections have the flag XXXXXX40" and "bss sections have the flag XXXXXX80" and leave it at that. The size of the sections shouldn't come into play (other than, perhaps, as some default if nothing else is specified).

What I'd really like is to be able to do something like this for COFF:

section 'data' data readable writeable align 16

-and-

section 'bss' bss readable writeable align 16

When (if) FASM combines sections in the same source file, it should do something reasonable, specifically, the combination of an initialized data section and an uninitialized data section should produce an initialized data section (including bloating out the section). It would be cool to issue a warning in case this happens.

As I pointed out in the last post, if you support the bss (uninitialized data) section flag, you should probably emit an error message if they use a data generating declaration.

Adding the BSS flag is really easy. I did that in a few minutes when playing around with the FASM source code (i.e., add the line <<db 3,"bss",19h,7>> to the formatter_symbols table). The code following the "section_flag" label needs to be tweaked to avoid OR'ing the bss and data flags together into the same value (though I'm not absolutely positive this is the only place this work needs to be done). The real trick is modifying the code that handles the data declaration directives so that it emits a warning if someone tries to declare data in a bss section.
Cheers,
Randy Hyde
Post 03 May 2007, 17:33
View user's profile Send private message Reply with quote
asmfan



Joined: 11 Aug 2006
Posts: 392
Location: Russian
asmfan 03 May 2007, 17:34
Wow Randall Hyde is here) Nice to meet you here.
I agree that needed /but not special necessary for good programmer Wink / some keyword to mark section as physical empty (but not virtual) to avoid some init data in it, although uninit data can be stored as last part of init data (as ms linker does - .data? is joined to .data).
also DATA directive after SECTION means initialized data flag, while lack of it means uninitialized.
Post 03 May 2007, 17:34
View user's profile Send private message Reply with quote
rhyde



Joined: 03 May 2007
Posts: 21
rhyde 03 May 2007, 19:07
asmfan wrote:
Wow Randall Hyde is here) Nice to meet you here.
I agree that needed /but not special necessary for good programmer Wink / some keyword to mark section as physical empty (but not virtual) to avoid some init data in it, although uninit data can be stored as last part of init data (as ms linker does - .data? is joined to .data).

The only problem with the "not necessary for good programmer" policy is that "not necessarily good programmers" often use the product.

Quote:

also DATA directive after SECTION means initialized data flag, while lack of it means uninitialized.

Alas, the lack of it does *not* set the uninitialized data flag ($80). This is, perhaps, a defect in the design of COFF, I haven't looked into why you would want to have both flags set (maybe specifiying that the last part of the section is uninitialized data?). In any case, I'm trying to eliminate linker warnings which are easy enough for advanced programmers to filter out, but freak out beginners. Of course, I wonder what the linker winds up doing when it has two sections that have both flags set. That would be an interesting situation to try and resolve. I personally feel more comfortable keeping initialized and uninitialized data in separate sections; sure, the linker might concatenate the sections when forming the final executable, but for OBJ files, I'd want them kept separate.
Cheers,
Randy Hyde
Post 03 May 2007, 19:07
View user's profile Send private message Reply with quote
vid
Verbosity in development


Joined: 05 Sep 2003
Posts: 7103
Location: Slovakia
vid 03 May 2007, 19:22
BSS section is NOT uninitialized. It is zeroed (due to any definition i can find).

BTW, That's why you have to use this
Code:
int MyVar=1;    
instead of
Code:
int MyVar=0;    
in C, if you want the variable to be physically present in resulting file (for later external modification etc...)

So "bss" is not probably not really same as "uninitialized"...
Post 03 May 2007, 19:22
View user's profile Send private message Visit poster's website AIM Address MSN Messenger ICQ Number Reply with quote
rhyde



Joined: 03 May 2007
Posts: 21
rhyde 03 May 2007, 20:49
vid wrote:
BSS section is NOT uninitialized. It is zeroed (due to any definition i can find).

This is true. However, the "uninitialized data" flag in the COFF section header is simply telling us that the data (which is all zeros) is not physically present in the object code file, it is the loader's responsibility to zero out memory when it loads the program into memory.

Quote:

So "bss" is not probably not really same as "uninitialized"...


Traditionally, BSS is the section name given to the "uninitialized" section. It wasn't always zeroed, but when timesharing OSes came around in the 1960s and security became a concern, the "uninitialized sections" were zeroed out when the program was loaded into memory. Languages like C came to rely upon this implicit initialization.

In any case, the sections I'm talking about *are* zeroed. They are called "uinitialized" because the programmer doesn't specifically provide an initial value for each value in that block -- the assumption is either that whatever initial value it has is irrelevant, or that (in modern OSes) it is automatically initialized with zeros when loaded into memory.

The difference between the "initialized data" and "uninitialized data" flags in the COFF format is file size. Because initialized data section might contain values other than zero, each and every byte of an initialized data section has to be present in the executable file. For uninitialized data sections, there is no need to take up one byte of space for each variable byte in the program; instead, all you need is the size of the section and the OS can automatically reserve that storage (and, as it turns out, zero out that storage). This makes EXEs a whole lot smaller if you've got a lot of static, uninitialized, data.

The problem I'm reporting is that the COFF section header is rather stupid. It has one bit for initialized data sections and a separate bit for uninitialized sections. Therefore, it is physically possible to set both bits (and, in certain circumstances, it appears that FASM does exactly this). However, having both bits set doesn't make sense (at least, not to me). You can't have *both* attributes for the same block of data, it's either initialized or not. Now the COFF section header *does* provide two fields: SizeOfInitializedData and SizeOfUninitializedData, so I assume that it *might* be possible to have initialized data at the beginning of a section and specify a block of uninitialized data at the end of the section, but as I mentioned in a previous post, it's a bit difficult to merge two such sections (containing both initialized and uninitialized data).

In any case, I'm winding up with some cases where FASM winds up setting both of these flag bits (and other times does not) and the Microsoft linker likes to complain at that point. My preferred solution is to be able to explicitly state that a given section contains initialized data or not.
Cheers,
Randy Hyde
Post 03 May 2007, 20:49
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.