(Login MCalkins) C-Forum Posted Sep 15, 2011 9:25 AM
Thank you for the response. I definitely need to do more research.
I need to emphasize that I am coming at this from an Assembly perspective, and am trying to relate everything back to Asm. A lot of C makes sense in that regard, but not all of it, at least not right away.
>Pointers are stored in memory just like any other variable.
I understand that that would (obviously) be the case when the pointer is declared, such as.
void * ptr;
I guess I don't quite see the point of doing it otherwise. It seems that the offset is something the compiler should be able to track. I need to do more research on how C works at a low level.
>FileName = otherLocation
I wasn't aware that that was possible. I was under the impression from:
>WriteConsoleW here will output the actual file name returned by GetModuleFileNameW because they are both using the erroneous memory address, &FileName.
>will be writing to memory that holds who-knows-what
Ouch. That's a bad mistake. My defense is that I am a n00b at C. :-(
>I expect that the other WriteConsoleW functions don't work, though. Do they?
Actually, they do...
(I reduced the size of the buffer, expecting the else block to display the error message, but it didn't display anything. I don't think the else block is executing. I'll figure that out later. Probably a syntax error.)
The WriteConsoleW calls seem to work correctly with and without the &. It seems to me that one or the other shouldn't work, but they both seem to. It almost makes me wonder whether GCC is automatically fixing my stupidity. I would doubt it, but the only other thing that I can think of is WriteConsoleW figuring out that I screwed up, but that seems even more implausible...
Re: Constant numbers for pointers in EXE
Again, I need to do more research on this also. I have researched PE files in the past, but I don't remember everything that I read.
>because those numbers will likely change every time your EXE is run.
Windows .EXEs and .DLLs all have preferred base address. Since each program is loaded in a private virtual address space, it shouldn't conflict with any other program. The shared .DLLs have preferred base offsets precalculated not to conflict with each other. As long as there is no conflict (which there shouldn't be), the image should be loaded to the same address every time. In case there is a conflict, there is a relocation table (the .reloc section) that tells the OS where and how to patch the offsets in the code.
Obviously, this affects statically allocated variables. I would think that any variables declared outside of any function should be static. Dynamically allocated variables, such as ones declared within functions, should be allocated on the stack, I would think, and accessed as a constant offset from EBP, so should not ever need relocation.
>but for non-constant (read-write) data, you have to ask the OS for such memory, and you can't predict where the memory will be located.
Again, I'm trying to relate this to Asm. C might be different from what I expect. However, I think it has to do with which section the variable is in. The basic sections that I am familiar with are .text for code, .data for initialized data, and .bss for uninitialized data.
I think .text is, in theory, read only (at least I treat it as such). So I guess "constant" data could go in .text.
.data is read/write. Statically allocated, non-constant, initialized data would go here. I would expect the msg0, msg1, and crlf arrays to go here.
.bss is read/write. Statically allocated, non-constant, uninitialized data would go here. I would expect the Filename array to go here.
dynamically allocated data would go on the stack, and would be read/write.
>but for non-constant (read-write) data, you have to ask the OS for such memory, and you can't predict where the memory will be located.
Since .data and .bss are read/write and statically allocated, it should be possible to know the offsets. You shouldn't need to allocate anything extra from the OS unless there is something that needs to be dynamically allocated that is too big, or potentially too big for the stack.
Some info on PE files (Some of which I've read in the past, but am still fuzzy on):
I guess the thing that I don't really like about C is actually one of the reasons C is so popular and universal, namely, the fact that it is platform independent. I know how to program for one platform: x86. But C was designed to be platform independent, and gcc is mainly a linux/unix compiler. So, I guess I have some sort of prejudice that if I go trying to read about C compilers, that I will find a bunch of general platform independent stuff, or perhaps unix specific stuff that won't apply to me. On the other hand, there is probably information that is too specific, dealing with specific borland or microsoft compilers. I guess the ideal information would be specific to x86 DOS and Windows, but covering any possible variation between MSVC, MinGW, and OpenWatcom. (I guess I'm coming up with excuses. I'm sure the info is out there; I'm just not looking for it. I don't want to get bogged down reading about how gcc works on Linux, because I really don't care at this point.) I need to stop being lazy and actually read more.
And of course, even if I know how to code for a specific platform, I should also know how to write cross platform C programs, which is C's strong point.
Regards,
Michael
P.S.
Well, this is embarrassing. When I reduced the size of the buffer, I forgot to reduce the nSize value. Also, I was thinking GetModuleFileNameW would return 0, but it returns nSize. So, I should be checking to see if the return value == nSize, and whether Filename[nSize-1] != 0...
:-(