The MASM Forum

General => The Workshop => Topic started by: felipe on May 24, 2018, 02:24:32 PM

Title: My third 64 bit console app...
Post by: felipe on May 24, 2018, 02:24:32 PM
I'm doing it well? (At least the program works correctly, after writting to the console press enter and the program finish...):


;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; This file was created by Felipe at 2018-05-24.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

option casemap:none
include \masm32\include64\win64.inc
include \masm32\include64\kernel32.inc
includelib  \masm32\lib64\kernel32.lib

.data
inbuff      byte    256 dup(" ")

.data?
chrsread    dword   ?

.code
start   proc
        sub     rsp,40      ; Shadow space + stack alignment.

        call    AllocConsole

        mov     rcx,STD_INPUT_HANDLE
        call    GetStdHandle

        add     rsp,40      ; Restores the stack.

        push    NULL        ; Reserved.

        sub     rsp,40      ; Shadow space + stack alignment.

        mov     rcx,rax     ; stdin.   
        lea     rdx,inbuff
        mov     r8,256      ; Chars to read.
        lea     r9,chrsread
        call    ReadConsole

        add     rsp,8

        call    FreeConsole

        xor     rcx,rcx
        call    ExitProcess

        add     rsp,40      ; Restores the stack.
start   endp
        end


.exe attached.
Title: Re: My third 64 bit console app...
Post by: aw27 on May 24, 2018, 04:38:16 PM
Does not crash this time but is wrong.
Try like this:


option casemap:none
include \masm32\include64\win64.inc
include \masm32\include64\kernel32.inc
includelib  \masm32\lib64\kernel32.lib

.data
inbuff      byte    256 dup(" ")

.data?
chrsread    dword   ?

.code
start   proc
        sub     rsp,40      ; Shadow space + stack alignment + STACK VARIABLES SPACE FOR THE WHOLE PROCEDURE.

        call    AllocConsole

        mov     rcx,STD_INPUT_HANDLE
        call    GetStdHandle

        ;add     rsp,40      ; WRONG

        ;push    NULL        ; Reserved. DON't DO PUSHES

        ;sub     rsp,40      ; Shadow space + stack alignment. NO

  mov qword ptr [RSP+32], NULL ; LIKE THIS
        mov     rcx,rax     ; stdin.   
        lea     rdx,inbuff
        mov     r8,256      ; Chars to read.
        lea     r9,chrsread
        call    ReadConsole

        ;add     rsp,8 ; WRONG

        call    FreeConsole

        xor     rcx,rcx
        call    ExitProcess

        ;add     rsp,40      ; WRONG. YOU WILL NOT COME HERE
start   endp
        end

Title: Re: My third 64 bit console app...
Post by: mineiro on May 24, 2018, 09:52:56 PM
Hello felipe, you're on the right path, keep walking.
At start of your procedure (sub rsp, ??) just ignore for a while that value and keep coding. After your procedure is done, get the function that have more parameters inside your procedure and based on that you have a value to be inserted at sub rsp, ??. Well, it's a memory eater as you can see because you alloc all memory need. Next challenge can be local variables inside your procedure.
One thing to remember are odd and even parameters to stack alignment. Other thing are leaf functions (the one that don't call others), they can be seen as different way.
Title: Re: My third 64 bit console app...
Post by: felipe on May 25, 2018, 03:15:02 AM

option casemap:none
include \masm32\include64\win64.inc
include \masm32\include64\kernel32.inc
includelib  \masm32\lib64\kernel32.lib

.data
inbuff      byte    256 dup(" ")

.data?
chrsread    dword   ?

.code
start   proc
        sub     rsp,40      ; Shadow space + stack alignment + STACK VARIABLES SPACE FOR THE WHOLE PROCEDURE. Ok i think i understand             
                                  ;    this. The extra parameters go "above" the shadow space.
        call    AllocConsole

        mov     rcx,STD_INPUT_HANDLE
        call    GetStdHandle

        ;add     rsp,40      ; WRONG   I did this based in "the caller is responsible of cleaning the stack". So i thought this must be done until
                                    ;   call to a procedure that needs more stack space. Seems like in this simple program case windows clean all for us 
                                    ;     when the process is done?
        ;push    NULL        ; Reserved. DON't DO PUSHES. So we can only do pushes when we are using a stack frame?

        ;sub     rsp,40      ; Shadow space + stack alignment. NO

  mov qword ptr [RSP+32], NULL ; LIKE THIS.
        mov     rcx,rax     ; stdin.   
        lea     rdx,inbuff
        mov     r8,256      ; Chars to read.
        lea     r9,chrsread
        call    ReadConsole

        ;add     rsp,8 ; WRONG

        call    FreeConsole

        xor     rcx,rcx
        call    ExitProcess

        ;add     rsp,40      ; WRONG. YOU WILL NOT COME HERE. I know, but i thought it would be good coding practice (not too efficient 
                                    ;   really).
start   endp
        end


Thanks, i have a lot to learn with this (i mean 64 bits programming), so i will not expect all the answers for my questions right now. But thank you very much to both anyway.  :icon14: :icon14:
Title: Re: My third 64 bit console app...
Post by: aw27 on May 25, 2018, 03:50:04 AM
Quote
;I did this based in "the caller is responsible of cleaning the stack". So i thought this must be done until
;   call to a procedure that needs more stack space. Seems like in this simple program case windows clean all for us 
;     when the process is done?
You can do but you should not do, if a procedure calls 1000 times other procedures you will spend a lot of time reserving and clearing stack. So, all should be done in the beginning of the procedure reserving space for the procedure that will use the most stack and keeping in mind that all procedures will be called with the stack aligned.

Quote
So we can only do pushes when we are using a stack frame?
The problem with the pushes is that they change the alignment.
So, if you align in the beginning of the procedure why are going to misalign?

All right, these things take time to understand.  :t

Title: Re: My third 64 bit console app...
Post by: felipe on May 25, 2018, 06:58:49 AM
Thanks again.  :icon14:
Title: Re: My third 64 bit console app...
Post by: mineiro on May 25, 2018, 07:07:53 AM
When program is loaded on memory rsp have a value ???????8h, we need subtract 1*8 bytes to align to a multiple of 16, so rsp == ???????0, now we can 'call' an external function (non leaf).
Next is necessary reserve space to shadow space (rcx,rdx,r8,r9), 4*8.
Next is to a function that use more parameters inside your procedure (ReadConsole) that need 1 argument on stack == 1*8.
Sub rsp, 1*8+4*8, so 1(parameter)+4(shadow) == 5, stack aligned (odd + odd rsp == even), it's ok. If even, you can do your own way or just add 8 to that value.
Again, at start of your procedure after you alloc memory to shadow space you can store rcx,rdx,... into that memory variables, not sure if this helps a diagnosis when program have a fault but we ignore that (Exception handler?).

When you push that value you're going from even (???????0) to odd (???????8), any values are ok to a leaf function, but function that call other functions gets in trouble.

edited --- odd and even :)
Title: Re: My third 64 bit console app...
Post by: hutch-- on May 25, 2018, 01:05:24 PM
 :biggrin:

Now you know why I bothered to write an adjustable stackframe macro for procedure entry and exit. With Win32 using ML.EXE a procedure was a simple construction, MASM automatically produced the entry and exit to a procedure which you could override if you did not want a stack frame but ML64 does not do that as the 64 bit calling convention is a lot more complicated. With procedures over 4 arguments you need a stack frame if you are not immediately aware of the stack location for passed arguments and with a stack frame you can directly allocate LOCAL variables to do sensible things like preserve and restore registers.

The point with the stackframe macro was that it ensured correct alignment without having to try and twiddle the stack manually.

To call a procedure I wrote the macro "procedure_call" and use a number of wrappers to call it ("invoke" and a few others) that puts the arguments in the right place, handles the copying of the first 4 args into shadow space then loads the rest of the arguments (if there is more than 4) into the correct stack locations.

Once you have the two macros working together the stackframe procedure can be used in a simple and reliable manner with the arguments in the right place and as many LOCAL variables as you need.
Title: Re: My third 64 bit console app...
Post by: Mikl__ on May 25, 2018, 03:48:52 PM
Hi, felipe!
I have decided to look by means of a value debugger which are returned by the GetStdHandle function. To the surprise I have found these values are constants.
|Windows
|10 x64
|Windows
|Seven x64
|Windows
|XP 32-bits
|Windows
|    98
|  UNIX
|and DOS
hInput|50h=101.0000b|   3 =00.11b|  3|   8 =0.1.0.00b|0=00b - standart input device
hOutput|54h=101.0100b|   7 =01.11b|  7|0Ch=0.1.1.00b|1=01b - standart output device
hError|58h=101.1000b|0Bh=10.11b|0Bh|10h=1.0.0.00b|2=10b - standart error device
Maybe it is worth using the fixed values, but not to cause every time the GetStdHandle function?
(http://masm32.com/board/index.php?action=dlattach;topic=4190.0;attach=5378;image)
Title: Re: My third 64 bit console app...
Post by: felipe on May 26, 2018, 04:15:23 AM
Quote from: Mikl__ on May 25, 2018, 03:48:52 PM
Maybe it is worth using the fixed values, but not to cause every time the GetStdHandle function?

Sounds ok, but maybe a little risky?  :idea:

Quote from: hutch-- on May 25, 2018, 01:05:24 PM
Now you know why I bothered to write an adjustable stackframe macro for procedure entry and exit.

I know is complicated now, even with a lot of help it will take me some time to handle this... :biggrin:

@mineiro: I liked your explanations. But i'm a little confused with how you are using the terms even and odd, there. I don't know how would be possible you get the rsp with an odd value, if is always decremented by 8 and it starts with a multiple of 8. Maybe you are using this terms to denote 16 byte aligned and not 16 byte aligned?  :idea:

Thanks to all.  :icon14:
Title: Re: My third 64 bit console app...
Post by: mineiro on May 26, 2018, 05:35:24 AM
Quote from: felipe on May 26, 2018, 04:15:23 AM
Maybe you are using this terms to denote 16 byte aligned and not 16 byte aligned?  :idea:
Yes sir, you take the point.
Title: Re: My third 64 bit console app...
Post by: daydreamer on May 26, 2018, 06:23:33 AM
Quote from: felipe on May 26, 2018, 04:15:23 AM
Quote from: Mikl__ on May 25, 2018, 03:48:52 PM
Maybe it is worth using the fixed values, but not to cause every time the GetStdHandle function?

Sounds ok, but maybe a little risky?  :idea:

Quote from: hutch-- on May 25, 2018, 01:05:24 PM
Now you know why I bothered to write an adjustable stackframe macro for procedure entry and exit.

I know is complicated now, even with a lot of help it will take me some time to handle this... :biggrin:

@mineiro: I liked your explanations. But i'm a little confused with how you are using the terms even and odd, there. I don't know how would be possible you get the rsp with an odd value, if is always decremented by 8 and it starts with a multiple of 8. Maybe you are using this terms to denote 16 byte aligned and not 16 byte aligned?  :idea:

Thanks to all.  :icon14:
nice attempt,but as all assembly demos usually exit with esc key I had to force it to Close,first run,before I read you checked for enter key instead
just thinking,after you make 9 attempts,but fails attempt 8 and attempt 9, you maybe succeded with Seven of Nine  :P  :lol:
Title: Re: My third 64 bit console app...
Post by: felipe on May 26, 2018, 07:46:47 AM
Quote from: mineiro on May 26, 2018, 05:35:24 AM
Yes sir, you take the point.

That's great mineiro, you are a good teacher.  :biggrin: Thanks.  :icon14:
Title: Re: My third 64 bit console app...
Post by: Mikl__ on May 26, 2018, 10:25:43 AM
Quote from: felipeSounds ok, but maybe a little risky?
Hi, felipe!
While you are studying and you still have nothing to lose. You run the risk, but at the same time gain experience and knowledge...
Title: Re: My third 64 bit console app...
Post by: felipe on May 26, 2018, 12:32:21 PM
That's true Mikl__ :icon14:
Title: Re: My third 64 bit console app...
Post by: Mikl__ on May 26, 2018, 01:08:23 PM
¡Hola felipe!
Examples for Win64 Iczelion tutorial (http://masm32.com/board/index.php?topic=4190.0) from 8 to 11 pages are Win x64 console samples
Title: Re: My third 64 bit console app...
Post by: felipe on May 26, 2018, 03:12:39 PM
 :icon14: Ok, thanks Mikl__. I think i will have a look there.
Title: Re: My third 64 bit console app...
Post by: jj2007 on May 27, 2018, 09:30:34 PM
Quote from: Mikl__ on May 25, 2018, 03:48:52 PMMaybe it is worth using the fixed values, but not to cause every time the GetStdHandle function?

Hi Mikl,

Hard-coded constants are a no-no, for obvious reasons. But one option could be to call GetStdHandle once in an initialisation routine, and to store the result in a global variable. That would save (in 64-bit land) 7 bytes per "print". In theory, however, the return value of GetStdHandle might change during the lifetime of a program - unless there is MSDN documentation that it remains constant.