Hi, this is my first day here, and I'm reading all the begginning Win32 tutorials. I have had experience with real mode programming on 80x86's, but flat model memory and protect mode programming is completely new to me. I used the TASM compiler. After about 20 times of crashing my first DOS program, I went online and was told to put in a stack segment (At that time, I didn't even know what that was). However, in these programs, there is no stack segment specifying the stack size or it's initial values! I know the stack is still around because of local varaibles, but it seems to work differently. For example stack is a LIFO system, last in first out, which I used with only push and pop. How does automatic variables which require random access fit onto the stack? Thanks.
Posted on 2005-05-26 15:16:40 by binarybob0001
You're right, in win32 the stack is already set up for you. I'm not 100% sure what you mean, i think you're asking- how is the stack used to store things other than push/pop values? Well, you can "allocate" space on the stack by altering the position of the stack pointer, called 'esp'. So to allocate, say 100 bytes:


sub esp,100


then from esp to esp+100 you have memory to play with so you can do anything like


mov ,eax
sub dword ptr ,3
not byte ptr


etc. etc.

then to "free" the memory you just add to esp again. In this case then, you'd do: add esp,100

hth
Posted on 2005-05-26 18:55:34 by stormix
Bob,

In Win32, the stack size and committed memory are set in the execulatble header, stack reserve and stack commit. This is usually set with the linker. If you are running 16 bit executables, you set the stack the old way.
Posted on 2005-05-26 19:29:02 by hutch--
In the flat memory model, you can use the LOCAL directive in MASM to allocate PROC variables on the stack. Variables allocated this way can be used only in the PROC where they're defined. MASM will insert code before the RET instruction to clean up the stack for you.


ViewProc proc hWin:DWORD, uMsg:DWORD, wParam:DWORD, lParam:DWORD
local hDC:DWORD
local Ps:PAINTSTRUCT
.
.
.
ret
Posted on 2005-05-26 20:08:14 by S/390
and one more thing:

if you're talking about nested automatic variables that can overlap, like in the example:

( c++)

int blah(int a, int b) {
    int temp1;

    if (1) {
        int temp2;
        temp2 = 7;
    }

    if (1) {
        int temp3;
        temp3 = 8;
    }

    temp1 = 2;
    return (a + b + temp1);
}

stupid compiler would allocate space for all 3 variables. a smarter ona would allocate for aonly 2. quite smarte would allocate space only for 1 variable. and finally very clever compiler will allocate space for no variable at all.

i assume you've already read stormix's post about allocating local variables :)
Posted on 2005-05-26 21:09:44 by ti_mo_n
Thanks everyone. I still have a couple of questions though. According to my reading every program thinks it has access to 4 gigs straight of memory. Where does the program start in memory. In real mode the program started after the stack segment which was why allocation was so important. In other words, does the program believe that it starts at address 0x00000000 where does it view its stack segment? How can you tell if there is no memory available? Sorry for asking so many questions in this one post, but I want to clear up all my memory questions so I can jump strait into windows in assembly! Another question, I was also told never ever to play with the code segment or stack segment registers(also their index registers). This seems to be just the opposite in winodws. Is esi, edi, ebp, ebx the only somewhat off limit registers (they must be pushed first), or are there other bad registers to play with?

Lastly, I would like to say that the information on this site is outstanding. I have been struggling for the past six months to make my own window API rapper in C++, but the windows API information seemed to be relitively limited particularly in advanced controls like RICHEDIT. I am also a member of code guru and while the enviroment and information there is also excelent, this site has more of the stuff I'm interested in. I know some of you may ask why after six months of work I don't break down and use MFC. The simple answer: I consider it poorly designed. My library may not be much better, but I'm gonna try.
Posted on 2005-05-27 02:27:16 by binarybob0001

Where does the program start in memory. In real mode the program started after the stack segment which was why allocation was so important. In other words, does the program believe that it starts at address 0x00000000 where does it view its stack segment?

Things like these are all taken care of by the compiler/linker and windows.
1. When compiling/linking, your program will be given a loading address. This is typically 400000h - but basically that's arbitrary, and could be anything. You can set this variable yourself, should you want to. Windows will try to load your executable at this address.
2. When windows loads your executable, it sets up pretty much everything for you. So, it also gives you a stack, and when your program starts, the registers are loaded with the relevant values.


How can you tell if there is no memory available?

If your program wants more memory on startup than is available, it won't run. Furthermore, if you're referencing data in your own address space, this will already have been setup by the compiler. Hence, only if you're trying to store variables in arbitrary places would you have this problem. If your exe loads, then you know your data sections fit in memory.
As for allocating more mem for your exe, this is a different question. It's done by calling API's and windows will tell you if there's available mem for you.


Sorry for asking so many questions in this one post, but I want to clear up all my memory questions so I can jump strait into windows in assembly! Another question, I was also told never ever to play with the code segment or stack segment registers(also their index registers). This seems to be just the opposite in winodws. Is esi, edi, ebp, ebx the only somewhat off limit registers (they must be pushed first), or are there other bad registers to play with?

Exactly what do you mean by code segment and stack segment registers? Modifying the esp register isn't that big a problem, especially if you stay within you allocated stack space.
As for the offlimit registers: basically you are right, however, keep in mind that when calling api's and the likes, you're going to be sharing the stack. For instance, if you create a window procedure, you should make sure to balance the stack before returning control to windows - otherwise things will go wrong.

Fake

Lastly, I would like to say that the information on this site is outstanding. I have been struggling for the past six months to make my own window API rapper in C++, but the windows API information seemed to be relitively limited particularly in advanced controls like RICHEDIT. I am also a member of code guru and while the enviroment and information there is also excelent, this site has more of the stuff I'm interested in. I know some of you may ask why after six months of work I don't break down and use MFC. The simple answer: I consider it poorly designed. My library may not be much better, but I'm gonna try.
Posted on 2005-05-27 04:54:30 by Fake51

In real mode the program started after the stack segment which was why allocation was so important. In other words, does the program believe that it starts at address 0x00000000 where does it view its stack segment?


Not true. In a DOS EXE file, the header information at the start of the file states where the program begins execution (relative to a DOS-assigned load address). It isn't necessarily the same place as the first stored byte of executable code. The header information also states where the stack is located (also relative to a DOS load address). It may not be apparent to you, but in real mode, segments are allowed to overlap, so that part of the stack segment may overlap the data segment. DOS compilers took advantage of that fact when generating code for the "small" memory model.

In Win32, the four "default" segment registers, CS, DS, ES, SS are set up so their corresponding segments overlap. The overlap is defined so that location 0 in CS is the same as location 0 in the other three segments. The result is that the program appears to have exactly one segment, regardless of which (of the four) segment register you used. Unlike real mode, the segments can potentially span the whole 4G address space allowed by 32-bit addressing. The primary exception to the single segment "flat" memory model is the use of FS to define a segment containing thread information.

The stack is located in memory where ESP says it's located. All the accessible memory locations are in the same segment.

How can you tell if there is no memory available?


That depends on what you mean by "no more" memory.? The idea of "no more" memory presumes the existence of memory management software. Win32 manages memory by using hardware "memory protection" features. There are API functions for getting "unallocated" storage from the OS.

I was also told never ever to play with the code segment or stack segment registers(also their index registers). This seems to be just the opposite in winodws. Is esi, edi, ebp, ebx the only somewhat off limit registers (they must be pushed first), or are there other bad registers to play with?


In protected mode, you must not play with any of the segment registers. Attempting to load arbitrary values into segment registers can cause an exception, halting your program. All eight of the main registers can be combined in various addressing modes, with only a few invalid combinations. When interacting with Windows, either by calling APIs, or being called by Windows, you must respect the register saving conventions.

I know some of you may ask why after six months of work I don't break down and use MFC.


Now, why would an assembly language programmer suggest using a C++ framework?
Posted on 2005-05-27 22:03:25 by tenkey

but the windows API information seemed to be relitively limited particularly in advanced controls like RICHEDIT.

If you're still using win32.hlp, get hold of the PlatformSDK: http://www.microsoft.com/downloads/details.aspx?FamilyID=EBA0128F-A770-45F1-86F3-7AB010B398A3&displaylang=en (or if you're not on broadband, order the CDs, you can use the online version at http://msdn.microsoft.com/ ).
Posted on 2005-05-29 20:10:31 by f0dder