I am writing an application and have a few questions specific to assembly programming (mainly how data is defined). Is it better to have certian types of data declared in the .data? over the .data section ? I am wondering where programmers would normally put variables like window handles, font handles, paint DCs, and windows procedures (Wndprocs).. Also, I've read from a previous post that having lots of uninitialized data can pose a serious problem in Windows NT4 and higher (2000, etc.). In this case it would be best to have all data under the .data section. Is this correct or do I have the .data section all mixed up with something else ? Thanks, Devin
If we're talking about an SDI application (Single Document Interface), then either in .data or .data? is fine. The only difference is in the size of the executable file. Unless you have thousands of structures and variables, the size difference between using only .data? and using only .data would be next to insignificant. However, if you're using MDI (Multiple Document Interface), you should use GetProcessHeap, and HeapAlloc for each window, so that important data doesn't get overwritten. (This isn't my technique, so I'd like to thank who gave it to me...but I can't remember his name! Thanks, whoever you are!). In this case, it would be wise to make one huge structure in the .data? section, and use that in combination with the heap to dynamically allocate the necessary space.
The main difference is .data and .data is the .data is stored and loaded from the .exe, while .data? is first allocated (then zeroed by the loader, so I've heard). If you are seriously compressing the size of your .exe, try to use .data? as much as is practable. Personally, I never depend on the loader to zero .data? items, so these go in my .data section. Safe is sure. As far as MDI docs go, it's best to think of these in object terms, each new window being a new object of the class, and prepare yourself to get some sort of THIS handle to the instance data. (THIS is the pointer to an object's instance data.) A good place for THIS is inside the window itself, leave yourself room for a dworn in your WINCLASS struct.
.data contains initialized data. Thus, those data are physically stored in a separate section in your executable file. If you define 10,000 dword variables in .data, your final executable would be at least 10,000*4 bytes. Normally, I would create a variable in .data if I want it to be initialized when the program loads. If I don't care about the initial value of the variable, or I must initialize it during runtime, I would put it in .data? Personally, I agree with TTom. Creating variables in .data? doesn't take disk space because the section is only marked as uninitialized data and when the executable is loaded, Windows will allocate a block of memory at least the size of the uninitialized section for it. The data in .data? section is initialized to zero. The values you obtain during runtime like various types of handles are best stored in .data? section because you don't care about their initial values and it will make your executable file smaller.
Hi, Iczelion and others, I am right now implementing these Virtual Data in Spasm. I have seen that, in several MASM produced PEs, which sources do have '?' data declared, there was no .BSS section. Ater i saw this, Radburn told me that this section would be build by the Assembler but simply pasted by the linker at the end of .data (and only Virtual size record of .data header increased to whished size). This solution seams to me better as it doesn't spoil as much memory as having 2 different sections for Data with two different 01000h alignements in memory. Do you agrea that this is the best and simplier solution? betov.
Thanks, I'll try to use .data? a little more.. Also since this macro sorta concerns data issues I was wondering how it works.. szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM I ripped this macro out of some other code and it seems to me that the assembler would just skip right over the Name portion of the macro because of the jmp lbl right before it. Also when compiling is this data that is being created more like a LOCAL variable, or is it more like .data .. hmm.. In my opinion, and I am not a very good programmer but it looks like using that macro to create a db of text would make it a global type of variable. Is there any way to adjust that macro so that i could just create a local variable that is destroyed whenever the PROC ends ? Thanks, I hope i made my self clear Devin. P.S. I think it would be cool to move the most popular posts to the top of the lists. Or have the entire message board sorted by Last Post. This would make it a lot easier to reply and respond to the more relevant discussion topics.
Here is that macro repeated: szText MACRO Name, Text:VARARG LOCAL lbl jmp lbl Name db Text,0 lbl: ENDM It's quite useful as it allows one to define a textstring anywhere in your .code area one is. It is used as: szText MyText, "Some text here." And expands to: jmp @F MyText BYTE "Some text here." @@: Yes, "MyText" would be a global variable. You might question why the jmp is needed? That is because this macro creates the string "inline" the .code segment. There is nothing wrong with this practice, though perhaps keeping all data strings in .data would make more sense (however, perhaps the programmer is deliberately hiding data, perhaps to fool the casual cracker, etc). I would not argue the 'jmp' is extraneous, hey, get real. 1 extra instruction ain't gonna effect your program's performance. Anyway, the code is correct, just not to my taste. I use a macro such as the following for text: szText MACRO Name, Text:VARARG .data Name db Text,0 .code ENDM This way, it directs the linker to place the text string in the .data area. It does have one drawback, it will produce nasty compiler errors if used inside the .data area. It's strictly for use in the .code section.
If you need data that has GLOBAL scope, place it in either the .DATA or .DATA? sections. Initialised data(.DATA) is if you need an initial value set in the data section, Uninitialised data(.DATA?) is if you need the GLOBAL scope but set the value for it at runtime, a window handle is a good example. If you don't need GLOBAL scope for the variable, make it LOCAL which is more efficient than both as the space is allocated on the stack. Stack is also faster than .DATA or .DATA? in terms of access. Regards, email@example.com
However take care NOT TO allocate more than 4K of LOCAL data in one single chunk on stack...as some Win95 and WinNT/2K will crash :) sometimes :) use HeapAlloc or GlobalAlloc instead... I have also heared that Win2K has some problems with LARGE nonintialised .data? sections...but did not get the chance to verify that...anybody else ?
Sorry I had not used HUGE .data? sections, but I know a problem with that text declaring macro: if you try to write something into that string, the program will crash, 'cause text is in read-execute code section.. Simple, but important ;)
The "jump-over" szText macro is ugly. First of all, your executable is larger than need be. You might argue that this is not very much, but when writing in *assembly*, it seems like heresy to do such a thing. TTom's ".data / defined data / .code" approach is much better. As to the "fool the casual cracker"...get real :). Everybody has acccess to something that will give a complete string reference, no matter where these strings are. If you really need security, do something that works. Never use the jump-over approach unless you really have to (I haven't yet seen a situation where the jump-over was necessary).