News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

Worked in Win7 Beta but not in Release

Started by GregL, January 21, 2010, 02:06:32 AM

Previous topic - Next topic

sinsi

Greg, the 'push rdi' aligns the stack to 16. Without it you would need 'sub rsp,28h'.
Light travels faster than sound, that's why some people seem bright until you hear them.

BogdanOntanu

After japeth's strong response in favor of aligning stack to 16 BEFORE the call is made ... I am also slightly confused :D
see this thread: http://www.masm32.com/board/index.php?topic=13202.0

I am in the process of re-reading the ABI documents and re-testing.

However in your example I see a push rdi in the prologue this PUSH performs an implicit sub rsp,8h.

This fixes the extra 8h from the return address and because of this a sub rsp,20h can be done by the compiler. And this is not against my statement that the stack should be aligned AFTER the call is made. At least this is how I see it now :D
Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

BogdanOntanu

Well, after re-tinking and re-considering ...

see here: http://msdn.microsoft.com/en-us/library/ew5tede7(VS.80).aspx

The relevant paragraph is this:

Quote
The stack will always be maintained 16-byte aligned, except within the prolog (for example, after the return address is pushed), and except where indicated in Function Types for a certain class of frame functions.

This "clearly" suggests that it is OK to have RSP not aligned immediately after the CALL is made.

And in this article:
http://blogs.msdn.com/oldnewthing/archive/2004/01/14/58579.aspx

It is said that:
Quote
Here's a sample:

void SomeFunction(int a, int b, int c, int d, int e);
void CallThatFunction()
{
    SomeFunction(1, 2, 3, 4, 5);
    SomeFunction(6, 7, 8, 9, 10);
}

On entry to CallThatFunction, the stack looks like this:
xxxxxxx0    .. rest of stack ..    
xxxxxxx8    return address    <- RSP

Due to the presence of the return address, the stack is misaligned. CallThatFunction sets up its stack frame, which might go like this:

    sub    rsp, 0x28

Notice that the local stack frame size is 16n+8, so that the result is a realigned stack.
xxxxxxx0    .. rest of stack ..    
xxxxxxx8    return address    
xxxxxxx0         (arg5)
xxxxxxx8         (arg4 spill)
xxxxxxx0         (arg3 spill)
xxxxxxx8         (arg2 spill)
xxxxxxx0         (arg1 spill) <- RSP

Now we can set up for the first call:

        mov     dword ptr [rsp+0x20], 5     ; output parameter 5
        mov     r9d, 4                      ; output parameter 4
        mov     r8d, 3                      ; output parameter 3
        mov     edx, 2                      ; output parameter 2
        mov     ecx, 1                      ; output parameter 1
        call    SomeFunction                ; Go Speed Racer!

This shows that the sub rsp,28h is done in the PROLOGUE of the function in order to keep the stack aligned to 16 in the function body and  compensate for the missaligned stack beacuse of the return address pushed by the CALL ABOVE and not for the CALL that will be made...

Hence the truth is in the middle: you must compensate for the return address... but in the prologue for the enclosing PROC and not at each INVOKE.

And the same rule apply for the Entry point of your program ... if written in ASM... then (normally) you will not be inside an enclosing PROC and you will need an sub rsp,8 or more if you use invoke there.


The rest of RAYMOND CHEN's article is also interesting showing how a compiler/assembler can avoid balancing the stack after each invoke inside a PROC...

Ambition is a lame excuse for the ones not brave enough to be lazy.
http://www.oby.ro

GregL

Quote from: sinsiGreg, the 'push rdi' aligns the stack to 16.

Quote from: BogdanOntanuHowever in your example I see a push rdi in the prologue this PUSH performs an implicit sub rsp,8h.

Yeah, I totally missed that.  :red  You guys are right.


sinsi

The only time the stack needs to be aligned is if you are calling a windows API. In your own procs it doesn't matter.
It is easier to stick to one way though, and I think that if you ensure the stack is aligned before the call you know
that in the called proc it is not aligned, so you need a 'sub rsp,x8h' if you call an API.

edit: that code doesn't work in the RC either.
    woohoo 100,000 posts!
Light travels faster than sound, that's why some people seem bright until you hear them.

GregL

#20
sinsi,

You mean the StartScreensaver.asm (or .c) code doesn't work on Win7 x64 RC?  Maybe it never worked on x64  ::).

Then the question, why doesn't the program work on x64?

GregL

Quote from: BogdanOntanuHence the truth is in the middle: you must compensate for the return address... but in the prologue for the enclosing PROC and not at each INVOKE.

And the same rule apply for the Entry point of your program ... if written in ASM... then (normally) you will not be inside an enclosing PROC and you will need an sub rsp,8 or more if you use invoke there.

From everything I have read, I think that is right. That's what I'm going to do.


sinsi

>You mean the StartScreensaver.asm (or .c) code doesn't work on Win7 x64 RC?
I assembled (and fixed) the asm code but not the c code (yuk!), tried SendMessageA instead of 'W' and, nope - win7 RC x64.

From windbg, a few things - GetCurrentThreadDesktopHwnd instead of GetDesktopWindow and the following error after SendMessage with !gle
Quote
LastErrorValue: (Win32) 0x36b7 (14007) - The requested lookup key was not found in any active activation context.
LastStatusValue: (NTSTATUS) 0xc0150008 - The requested lookup key was not found in any active activation context.
Light travels faster than sound, that's why some people seem bright until you hear them.

GregL

#23
Thanks sinsi.  I would be curious to see whether or not the code works on 32-bit Vista or Win7.

The workaround is to make a shortcut to C:\Windows\System32\PhotoScreensaver.scr /s (or whatever screensaver you are using). Not as versatile but it does the job.


ChillyWilly

im having a problem with reading a registry key in win7 64bit  :'(
can someone give me some insight on how to fix my code there?

http://www.masm32.com/board/index.php?topic=13194


GregL

Quote from: Greg LyonI would be curious to see whether or not the code works on 32-bit Vista and/or Win7.

Attached is the code and the.exe (32-bit).


sinsi

OK, I have a confession to make...I didn't actually have a screensaver selected so of course your code didn't work.
Now that I have one, both 64- and 32-bit programs work as expected.
Excuse me while I curl up and die of embarassment.
Light travels faster than sound, that's why some people seem bright until you hear them.

dedndave

i thought the real trick was stopping the screen-saver - not starting it

GregL

sinsi,

OK, so I am not going senile, I thought it worked on Win7 RC.  So, I am back to the original question.


Quote from: dedndavei thought the real trick was stopping the screen-saver - not starting it

I never had a need to do that.

sinsi

Could another program/service be stopping the message? Returning -1 for the message will stop the screensaver from kicking in.
If you set it to require a password on resume, apparently the return from the message is ignored, so no program can stop it starting.

me senile, not you.
Light travels faster than sound, that's why some people seem bright until you hear them.