Recent Posts

Pages: [1] 2 3 ... 10
1
Quote from: nidud link=topic=9218.msg101372#msg101372
If you add a call at top it make more sense
Ok. Could be necesary sometimes.

Thanks  :thumbsup:
2
Are you sure?

With my little understanding, I think you missed something:

empty4 proc arg1:QWORD,arg2:QWORD,arg3:QWORD,arg4:QWORD
    mov rax,arg3 ; the argument(s) needs to be used and you are going to debug with WinDbg
    ret
empty4 endp

Shadow space only is used in that way by callee when you are testing/debugging (can be used like usual locals in other case). No?

The debugger only look at the stack frame but the sample is a bit misguided. You would normally use the register (r8) here directly, and the assembler wouldn't bother saving the register to the stack in that case. If you add a call at top it make more sense:

    CoInitialize(0)

    ; now the registers RCX, RDX, R8, and R9 are trashed

    mov rax,arg3 ; so you need to use the stack

In this case arg3 is flagged as used and thus saved to the stack before the call.

I am not sure why you are worried about 0x60 bytes when a default stack is usually 1 meg or with PE linker options even greater. Long ago I learnt that a little padding here and there was highly virtuous. You are not saving memory here by trimming down to a theoretical limit, it is already allocated when the executable is built.

It's actually 0x80 + 0x60 + 8 for each level, two in this sample, but yes there's a large stack.

Quote
Now I never criticise the creative genius of making something and I admit I am not familiar with your notation but the options for stack frames above look like build options that you would use at the start of the file, not something that you can do for each procedure.

It's normally handled by the header files so it runs on auto by default but also possible to customize it for each procedure.
3
MasmBasic & the RichMasm IDE / Shadow space in 64-bit programming
« Last post by jj2007 on Today at 09:36:47 AM »
Shadow space (sometimes also called home space) is a badly understood concept in 64-bit programming. To quote Microsoft (my highlighting):
Quote
The x64 Application Binary Interface (ABI) uses a four-register fast-call calling convention by default. Space is allocated on the call stack as a shadow store for callees to save those registers.

Which means the shadow space is dedicated memory for saving four registers, precisely: rcx, rdx, r8 and r9.
The callee (i.e. the called proc) receives arguments 1-4 in registers rcx, rdx, r8 and r9. The callee can save them in the shadow space, but is not obliged to do so. In fact, debugging of, for example, CreateWindowEx shows that Windows often does not move the 4 registers into the shadow space; instead, it uses them directly ("fastcall").

Below is a simple example of a procedure with 7 arguments. It uses JBasic (which is included in the MasmBasic package), but other packages will do it very much the same way. Source and exe are attached, when debugging type y to stop at the int 3:
Code: [Select]
include \Masm32\MasmBasic\Res\JBasic.inc ; ## console demo, builds in 32- or 64-bit mode with UAsm, ML, AsmC ##
.code
useClv=0
SayHi proc arg1:SIZE_P, arg2, arg3, arg4, arg5, arg6, arg7  ; SIZE_P is QWORD for 64-bit and DWORD for 32-bit code
Local v1, v2, v3, v4, rc:RECT
  if @64 ; don't use in 32-bit code
mov arg1, rcx ; the callee uses one shadow space slot
jinvoke crt_printf, Chr$("Arg1 as register: %s", 13, 10), rcx
  else ; 32-bit code looks a bit simpler:
jinvoke crt_printf, Chr$("Arg1 'as is' in 32-bit: %s", 13, 10), arg1
  endif
  Print Str$("The arguments 1...7: %s %i %i %i %i %i %i", arg1, arg2, arg3, arg4, arg5, arg6, arg7)
  mov rc.left, 123
  Print Str$(" \nThe locals v1...v4 and rc.left: %i %i %i %i %i", v1, v2, v3, v4, rc.left)
  jinvoke MessageBox, 0, arg1, Chr$("Hi folks"), MB_OK or MB_SETFOREGROUND
  ret
SayHi endp
Init ; OPT_64 1 ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This program was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format.")
  Inkey Chr$("Int 3?", 13, 10, 10)
  cmp rax, "y"
  jne @F
INT 3
@@:
  jinvoke SayHi, Chr$("The text for the MessageBox"), 2, 3, 4, 5, 6, 7
  jinvoke MessageBox, 0, Chr$("That was easy, right?"), Chr$("Title"), MB_OK
EndOfCode

Console output:
Code: [Select]
This program was assembled with ml64 in 64-bit format.
Int 3?

Arg1 as register: The text for the MessageBox
The arguments 1...7: The text for the MessageBox 0 0 0 5 6 7
The locals v1...v4 and rc.left: 0 0 0 0 123

As you can see, arguments 2-4 are zero, i.e. the shadow space was not set for them. Here is the disassembly:
Code: [Select]
sub rsp, 8*QWORD ; 64 bytes reserved somewhere higher up, e.g. on entry of a proc
...
; jinvoke MyProc, 1, 2, 3, 4, 5, 6, 7 ; seven arguments
; mov qword ptr ss:[rsp+38],8                             | 38h=56 dec: unused here (we have only 7 args)
mov qword ptr ss:[rsp+30],7                               | 30h=48 dec: arg7
mov qword ptr ss:[rsp+28],6                               | 28h=40 dec: arg6
mov qword ptr ss:[rsp+20],5                               | 20h=32 dec: arg5

; NO mov qword ptr ss:[rsp+18],4                          | 18h=24 dec: arg4 is shadow space and does
mov r9d,4                                                 | NOT get filled; instead, arg4...arg1 go to
mov r8d,3                                                 | the registers rcx, rdx, r8, r9
mov edx,2                                                 | using the required size, normally DWORD but
lea rcx,qword ptr ds:[140001521]                          | pointer for "The text for the MessageBox"

call <sub_140001002>                                      | call SayHi: stack is 000000000012FF00
...
add rsp, 8*QWORD ; release the 64 reserved bytes
; SayHi proc arg1:SIZE_P, arg2, arg3, arg4, arg5, arg6, arg7 ; arg1...arg4 are the shadow space
push rbp                                                  | create a
mov rbp,rsp                                               | stack frame
sub rsp,B0                                                | create space for the local variables
mov qword ptr ss:[rbp+10],rcx                             | use the arg1 shadow space for storing rcx
mov rdx,rcx                                               | arg2: "The text for the MessageBox"
lea rcx,qword ptr ds:[140001448]                          | arg1: "Arg1 as register: %s\r\n"
call qword ptr ds:[<sub_140001808>]                       | CRT printf
...
leave                                                     | the short and efficient way
ret                                                       | to get rid of the stack frame

In the example above, the seven arguments require at least 7 QWORDs on the stack, but we used 8:
sub rsp, 8*QWORD      ; 64 bytes reserved somewhere higher up, e.g. on entry of a proc

If you plan to call e.g. CreateWindowEx with 11 arguments, reserve 12 or 16 QWORDs. Remember that the stack must always be aligned to 16 bytes, see above: call SayHi: stack is 000000000012FF00. In the moment when you are calling, the least significant byte of rsp must be 0.
4
 :biggrin:

I am not sure why you are worried about 0x60 bytes when a default stack is usually 1 meg or with PE linker options even greater. Long ago I learnt that a little padding here and there was highly virtuous. You are not saving memory here by trimming down to a theoretical limit, it is already allocated when the executable is built.

Now I never criticise the creative genius of making something and I admit I am not familiar with your notation but the options for stack frames above look like build options that you would use at the start of the file, not something that you can do for each procedure.

5
Hi Nidud!

option win64:3

empty4 proc arg1:QWORD,arg2:QWORD,arg3:QWORD,arg4:QWORD
    mov rax,arg3 ; the argument(s) needs to be used..
    ret
empty4 endp

Are you sure?

With my little understanding, I think you missed something:

empty4 proc arg1:QWORD,arg2:QWORD,arg3:QWORD,arg4:QWORD
    mov rax,arg3 ; the argument(s) needs to be used and you are going to debug with WinDbg
    ret
empty4 endp

Shadow space only is used in that way by callee when you are testing/debugging (can be used like usual locals in other case). No? 
6
Many in this site loves macros and try to sell those to everyone, but i like to see optimized code, not a new macro hell :sad:
7
16 bit DOS Programming / Re: Simple example to link with DJGPP
« Last post by TimoVJL on Today at 05:50:35 AM »
msdos.exe with cwsdpmi.exe works badly, have to press enter before program shows result.

Open Watcom C supports 386 too.

Perhaps a useful link for people, who have to use MS DOS.
https://dosgames.com/utilities.php
8
Are you saying you cannot produce varieties of stack frames. I can routinely do it in MASM.

No.

Quote
Yes we already know that, that is why if you don't use an argument list in masm you don't get the overhead of shadow space.

This produces,
Which disassembles to,

.text:0000000140001000 C8800000                   enter 0x80, 0x0
.text:0000000140001004 4883EC60                   sub rsp, 0x60

 :biggrin:

You literary create a stack frame for 28 arguments, the size of 7 shadow spaces, for each of them.

How to write shadow space.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

SET_STACK_FRAME 2, 2

empty4 proc arg1:QWORD,arg2:QWORD,arg3:QWORD,arg4:QWORD

    ret

empty4 endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

.text:00000001400010a0
.text:00000001400010a0 0x1400010a0:
.text:00000001400010a0 55                         push rbp
.text:00000001400010a1 488BEC                     mov rbp, rsp
.text:00000001400010a4 4883EC60                   sub rsp, 0x60
.text:00000001400010a8 48894D10                   mov qword ptr [rbp+0x10], rcx
.text:00000001400010ac 48895518                   mov qword ptr [rbp+0x18], rdx
.text:00000001400010b0 4C894520                   mov qword ptr [rbp+0x20], r8
.text:00000001400010b4 4C894D28                   mov qword ptr [rbp+0x28], r9
.text:00000001400010b8 488BE5                     mov rsp, rbp
.text:00000001400010bb 5D                         pop rbp
.text:00000001400010bc C3                         ret


In Asmc, skipping the shadow spase gives this result:

option win64:rsp noauto

empty4 proc arg1:QWORD,arg2:QWORD,arg3:QWORD,arg4:QWORD
    ret
empty4 endp

empty4:
        ret

Using the default mode:

option win64:3

empty4 proc arg1:QWORD,arg2:QWORD,arg3:QWORD,arg4:QWORD
    mov rax,arg3 ; the argument(s) needs to be used..
    ret
empty4 endp

empty4:
        mov     qword ptr [rsp+18H], r8
        push    rbp                   
        mov     rbp, rsp               
        sub     rsp, 32               
        mov     rax, qword ptr [rbp+20H]
        leave                           
        ret                             
9
The Workshop / Re: Syslink control
« Last post by jj2007 on Today at 04:50:15 AM »
Did you see what is it ?
It's for everyone and it's a prime source of informations.

Yves, a simple deb shows me all Windows messages - much more convenient than an extra window:
Code: [Select]
WndProc proc uses esi edi ebx hWnd, uMsg, wParam:WPARAM, lParam:LPARAM
  inc msgCount
  deb 4, "msg", chg:msgCount


In any case, your contribution has nothing to do with the question asked here. You are spamming my threads, mon cher ami :badgrin:
10
How to write shadow space.

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

SET_STACK_FRAME 2, 2

empty4 proc arg1:QWORD,arg2:QWORD,arg3:QWORD,arg4:QWORD

    ret

empty4 endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

.text:00000001400010a0
.text:00000001400010a0 0x1400010a0:
.text:00000001400010a0 55                         push rbp
.text:00000001400010a1 488BEC                     mov rbp, rsp
.text:00000001400010a4 4883EC60                   sub rsp, 0x60
.text:00000001400010a8 48894D10                   mov qword ptr [rbp+0x10], rcx
.text:00000001400010ac 48895518                   mov qword ptr [rbp+0x18], rdx
.text:00000001400010b0 4C894520                   mov qword ptr [rbp+0x20], r8
.text:00000001400010b4 4C894D28                   mov qword ptr [rbp+0x28], r9
.text:00000001400010b8 488BE5                     mov rsp, rbp
.text:00000001400010bb 5D                         pop rbp
.text:00000001400010bc C3                         ret
Pages: [1] 2 3 ... 10