The MASM Forum

64 bit assembler => 64 bit assembler. Conceptual Issues => Topic started by: nidud on March 04, 2021, 06:02:33 AM

Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 04, 2021, 06:02:33 AM
deleted
Title: Re: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: jj2007 on March 04, 2021, 06:23:53 AM
Quote from: nidud on March 04, 2021, 06:02:33 AMMicrosoft and GCC do this in reverse, in push-order which is right-to-left

Normally, the order is not an issue - except if you use those registers as arguments which are used for the 4 fastcall arguments:
include \Masm32\MasmBasic\Res\JBasic.inc ; ## builds in 32- or 64-bit mode with UAsm, ML, AsmC ##
BytesWritten dq ?
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.")
  jinvoke DeleteFile, Chr$("CreateFile.opened")
  if 1
mov eax, GENERIC_WRITE
mov ecx, FILE_SHARE_WRITE
mov edx, CREATE_ALWAYS
mov r8, FILE_ATTRIBUTE_NORMAL

jinvoke CreateFile, Chr$("CreateFile.opened"), eax, ecx, NULL, edx, r8, 0
  else
jinvoke CreateFile, Chr$("CreateFile.opened"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, 0
  endif
  xchg rax, rbx
  PrintLine Err$()
  jinvoke WriteFile, rbx, Chr$("Hello World, how are you?"), c$Len, addr BytesWritten, 0
  jinvoke CloseHandle, rbx
EndOfCode


Under the hood:
int3                                                      |
mov eax,40000000                                          |
mov ecx,2                                                 |
mov edx,2                                                 |
mov r8,80                                                 |

and qword ptr ss:[rsp+30],0                               |
mov r10,r8                                                |
mov qword ptr ss:[rsp+28],r10                             |
mov r10d,edx                                              |
mov qword ptr ss:[rsp+20],r10                             |
xor r9d,r9d                                               |
mov r8d,ecx                                               |
mov edx,eax                                               |
lea rcx,qword ptr ds:[1400013A9]                          | 1400013A9:"CreateFile.opened"
call qword ptr ds:[<sub_140001740>]                       |


Obviously, left-to-right order would fail when passing arguments in rcx and rdx.
Title: Re: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 04, 2021, 06:32:43 AM
Write order is not specific, only argument location.

        mov     dword ptr [rsp+28H], edx
        mov     dword ptr [rsp+30H], eax
        mov     dword ptr [rsp+20H], ecx
        mov     r9d, 4                 
        mov     r8d, 3                 
        mov     edx, 2                 
        mov     ecx, 1                 
        call    foo


Microsoft and GCC do this in reverse, in push-order which is right-to-left.

x64 does not have a PUSH order.
Title: Re: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 04, 2021, 08:02:16 AM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 04, 2021, 10:54:06 AM
> Of course it has. This is the main part of the convention which determine the position of each argument on the stack for a function call.

You may have a deviant terminology but I suggest that it has more to do with you supporting 32 bit STDCALL than 64 bit FASTCALL. With the x64 ABI you can have left to right, up to down, inside out and upside down or even a random distribution, as long as all the arguments end up in the right sequence, it will work but PUSH order, forget it.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: jj2007 on March 04, 2021, 12:28:43 PM
Quote from: hutch-- on March 04, 2021, 10:54:06 AMWith the x64 ABI you can have left to right, up to down, inside out and upside down or even a random distribution, as long as all the arguments end up in the right sequence, it will work

See Reply #1. Remember the "register gets overwritten" error?
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 05, 2021, 12:22:21 AM
Yes, it was a bad example but I understood what he was aiming at. It seems that many paddling around trying to understand x64 FASTCALL have yet to fully understand how it works.

This is among the reasons why shadow space is required in some situations but the general drift is don't use any of the first four registers in the first four arguments.

The layout of x64 FASTCALL is primarily designed for a 64 bit C compiler but MASM can be configured to properly use x64 FASTCALL.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 05, 2021, 01:14:22 AM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 05, 2021, 12:28:45 PM
The problem as I see it is that you are shifting across a large variety of calling conventions and effectively blurring the distinctions. We all know how 32 bit Windows STDCALL worked, push/call notation and the specs are publically available for Microsoft x64 Windows and there is no leakage across the two.

The Microsoft x64 ABI FASTCALL does not use PUSH at all and the notion of a PUSH order may be convenient when you are dealing with a multitude of different calling conventions but it misrepresents the 64 bit Windows FASTCALL. Now as I am sure that you understand the M$ FASTCALL, the obvious is that when you write the 1st 4 args to registers,

mov rcx, 1
mov rdx, 2
mov r8, 3
mov r9, 4

is the same as

mov r8, 3
mov rcx, 1
mov r9, 4
mov rdx, 2

While the identical data is written to the 1st 4 registers, they are not written in the same order as it simply does not matter, the 4 arguments are written to the correct registers. The idea of PUSH order is incorrect here, its the WRITE order that matters. With the 5th and higher arguments written to the stack after the 4 shadow space positions, they don't have to be written in PUSH order either. For each 64 bit location on the stack, if you write the correct data to each 64 bit location, you can write it in any order you like.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 05, 2021, 09:55:56 PM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 05, 2021, 10:52:05 PM
 :biggrin:
Quote
It actually changes everything and it's done so by design. RCX is the most important register as it is used as a counter (hence the C) and operand for various shift operations. RDX is also a better choice than R8..Rn as it has two byte registers. Compilers will therefor use (spill) RAX, RCX, and RDX for loading arguments from the right and assign value to RCX at the end.
This is MS-DOS level thinking and it is not x64 Windows ABI compliant.

ax = accumulator
bx = base address
cx = counter
dx = data
si = source index
di = destination address
sp = stack pointer
bp = base pointer

With Win64 ABI you are free from this ancient thinking, in the 1st 4 registers in FASTCALL you can put anything you like as long as you don't over write registers with other registers.

Now when you make a call in 64 bit Windows FASTCALL, you have written values to the first 4 registers but in the procedure that you are calling you can directly use them, assign them to locals, copy them to other registers and even save some of the system registers and save them there.

There is no reason why a compiler cannot be fully ABI compliant, slopping data around with unsound assumptions produces junk code, something a compiler should not do.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: jj2007 on March 05, 2021, 11:29:49 PM
Quote from: hutch-- on March 05, 2021, 10:52:05 PMas long as you don't over write registers with other registers.

Yep, and that's the only reason why the "push order" matters a little bit.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 06, 2021, 01:20:46 AM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: TimoVJL on March 06, 2021, 01:34:59 AM
Windows x64 ABI and C/C++ rules, so be calm.

BTW:
Nice feature of programming, when we old people go to pension, our software still runs, even after we die or vanish :smiley:
Hardware workers are in better case, their work are usable a lot of longer.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: HSE on March 06, 2021, 01:59:52 AM
Quote from: nidud on March 06, 2021, 01:20:46 AM
as this is not a "real" FASTCALL convention.

Things begin to make sense  :thumbsup:

Thanks.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 06, 2021, 08:28:11 AM
> The point is that RCX and RDX has other qualities (or privileges) than R10 and R11.

The catch here is you have to go back a very long way with your instruction choice to find these things. With the exception of the MOVS STOS and SCAS which have special case circuitry due to their popularity over a long period, these fixed register instructions are mainly old junk that is best avoided in 64 bit Windows as they are often very slow.

Now as far as FASTCALL, in this context of Microsoft Windows x64 ABI for Windows 10, its specifications are known by most programmers who write 64 bit Windows code and it is not some open sauce binding set of rules that bridge across multiple OS versions. The UNIX guys have their own specs and I have no doubt that other platforms have theirs as well but there is little in common between them.

I mean seriously, who cares what you need for MAC on MIPS ?

I have no doubt that you well understand the Win64 x64 ABI but your description of how it works shows the cross influence of working across different OS types and platforms.

Here is a simple byte copy procedure using REP MOVSB.

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

NOSTACKFRAME

bcopy proc

  ; rcx = src
  ; rdx = dst
  ; r8  = count

    mov r11, rsi
    mov r10, rdi

    mov rsi, rcx
    mov rdi, rdx
    mov rcx, r8

    rep movsb

    mov rsi, r11
    mov rdi, r10

    ret

bcopy endp

STACKFRAME

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

No stack frame and using some of the extra registers rather than using LOCALs to preserve RSI and RDI and arguments read at the proc end directly from registers in accordance with the Microsoft 64 bit FASTCALL ABI without the need to read shadow space.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: HSE on March 06, 2021, 09:02:58 AM
Hi Hutch!

Quote from: hutch-- on March 06, 2021, 08:28:11 AM
Microsoft 64 bit FASTCALL ABI without the need to read shadow space.

I readed an article by Microsoft from twelve years ago that say that in 64 bits there is only one calling convention, the (Microsoft) "x64  calling convention". Fastcall it's not part of the name. They only say: is a fastcall-like calling convention. That is a lot more clear for me that, you know, I know very little :biggrin:   

Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 06, 2021, 09:08:42 AM
Hi Hector,

I think its a case of a rose by any other name still has thorns.  :tongue:
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 06, 2021, 10:50:54 AM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: daydreamer on March 06, 2021, 11:57:10 PM
Quote from: nidud on March 06, 2021, 10:50:54 AM
Quote from: hutch-- on March 06, 2021, 08:28:11 AM
> The point is that RCX and RDX has other qualities (or privileges) than R10 and R11.

The catch here is you have to go back a very long way with your instruction choice to find these things. With the exception of the MOVS STOS and SCAS which have special case circuitry due to their popularity over a long period, these fixed register instructions are mainly old junk that is best avoided in 64 bit Windows as they are often very slow.

True, newer CPU's actually favors the MOVS instructions over XMM but the usage and functionality of the shift/rotate instructions are the same, so nothing has changed in that regard. MOVSX is a relatively new instruction that didn't exist back in the DOS area. An immediate operand was also added to most instructions using CL as count.

    SHL, SHR, ROR, ROL, SAL, SAR, RCL, RCR, SHLD, SHRD, ...


isnt in DOS 16bit minimum size MOVS,STOS instructions smallest
they are wrapping MOV [edi],[esi] and inc alternative dec instructions
my theory when they went from old hardware wired with good old opcode->circuitry,to modern microcode architechture,longer snippets of microcode is needed to perform all those instructions,compared to simpler modern mov instructions
with 64bit opcodes+many of them +8bytes of immediate,adress its pointless to use it as smaller size instruction
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 07, 2021, 08:45:11 AM
> However, the arguments here was right-to-left versus left-to-right and the consequences of choosing one over the other. Or more to the point, the origin of the idea of the choice made.

The argument was about you use of PUSH ORDER done by association with a collection of technologies that belong in the past. I make the same point, Windows x64 ABI only requires the WRITE order to be correct, there is no PUSH ORDER. For the obvious reason, I don't see the association between DOS C to x64 Windows and that is because there is none. You may also note that under DOS in a non-re-entrant environment there were no formal calling conventions as it did not matter, they all did their own thing.

Win32 had a PUSH ORDER using push/call notation via STDCALL, Win x64 writes addresses to locations on the stack WITHOUT CHANGING THE STACK ADDRESS.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: jj2007 on March 07, 2021, 09:08:45 AM
Quote from: hutch-- on March 07, 2021, 08:45:11 AMWin32 had a PUSH ORDER using push/call notation via STDCALL, Win x64 writes addresses to locations on the stack WITHOUT CHANGING THE STACK ADDRESS.

Hutch, I think we all know that we are not talking about a "push order" in the old Win32 sense...

Quote from: jj2007 on March 05, 2021, 11:29:49 PM
Quote from: hutch-- on March 05, 2021, 10:52:05 PMas long as you don't over write registers with other registers.

Yep, and that's the only reason why the "push order" matters a little bit.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 07, 2021, 12:16:13 PM
I have no doubt that most DO understand how the win32 push order works but I complained about it being applied to windows x64 because its simply wrong. Anyone who can read the Win64 ABI know that values are written to the 1st 4 registers and depending on how the call is done, the same 4 registers are written to shadow space then all other arguments are written after that.

The difference is MOV rather than PUSH, PUSH changes the stack, MOV does not and that is the spec for Windows x64.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: jj2007 on March 07, 2021, 02:34:13 PM
Quote from: hutch-- on March 07, 2021, 12:16:13 PMvalues are written to the 1st 4 registers and depending on how the call is done, the same 4 registers are written to shadow space then all other arguments are written after that.

My understanding is that the 4 registers rcx rdx r8 r9 are not written to shadow space before the call; it is the called proc's task to write them to shadow space if needed.

IMHO it is better to deal first with the higher arguments, in order to be able to use rcx rdx r8 r9 also as arguments. Afterwards, the first 4 arguments can be assigned to rcx rdx r8 r9 without risking to overwrite arguments.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 07, 2021, 05:36:53 PM
Interesting view but its not part of the x64 ABI. The ABI only specifies the first 4 registers for the first 4 arguments and after the first 4 argument shadow spaces locations, any following arguments written to the 64 bit locations. Its a mistake that many make trying to append their own rules to an existing specification.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 07, 2021, 11:36:55 PM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 08, 2021, 01:58:38 AM
You are mixing the creation of a stack frame with passing arguments to a procedure. From a calling procedure, the stack must be aligned for another procedure call due to the CALL mnemonic and the RET mnemonic, this is why you provide multiple stack frame designs for different tasks.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: jj2007 on March 08, 2021, 02:44:39 AM
Quote from: hutch-- on March 07, 2021, 12:16:13 PMAnyone who can read the Win64 ABI know that values are written to the 1st 4 registers and depending on how the call is done, the same 4 registers are written to shadow space then all other arguments are written after that.

The caller does not write the regs to shadow space. The callee may write them to shadow space.

https://docs.microsoft.com/en-us/cpp/build/x64-calling-convention?view=msvc-160
QuoteThe caller is responsible for allocating space for the callee's parameters. The caller must always allocate sufficient space to store four register parameters, even if the callee doesn't take that many parameters.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 08, 2021, 02:52:54 AM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 08, 2021, 03:59:40 AM
Are you saying you cannot produce varieties of stack frames. I can routinely do it in MASM.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 08, 2021, 04:09:18 AM
> The caller does not write the regs to shadow space. The callee may write them to shadow space.

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,
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤

entry_point proc

    rcall empty,1,2,3,4

entry_point endp

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

empty proc

    ret

empty endp

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

Which disassembles to,

.text:0000000140001000 C8800000                   enter 0x80, 0x0
.text:0000000140001004 4883EC60                   sub rsp, 0x60
.text:0000000140001008 49C7C104000000             mov r9, 4
.text:000000014000100f 49C7C003000000             mov r8, 3
.text:0000000140001016 48C7C202000000             mov rdx, 2
.text:000000014000101d 48C7C101000000             mov rcx, 0x1
.text:0000000140001024 E800000000                 call sub_140001029
.text:0000000140001024
; --------------------------------------------------------------------------
; sub_140001029
; --------------------------------------------------------------------------
sub_140001029   proc
.text:0000000140001029 C8800000                   enter 0x80, 0x0
.text:000000014000102d 4883EC60                   sub rsp, 0x60
.text:0000000140001031 C9                         leave
.text:0000000140001032 C3                         ret
sub_140001029   endp
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 08, 2021, 04:25:07 AM
For nidud,

Stackframes galore !

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

    include \masm32\include64\masm64rt.inc

    .code

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

entry_point proc

    rcall empty, 1,2,3,4
    rcall empty2,1,2,3,4
    rcall empty3,1,2,3,4
    rcall empty4,1,2,3,4

entry_point endp

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

ALTSTACKFRAME

empty proc

    ret

empty endp

STACKFRAME

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

NOSTACKFRAME

empty2 proc

    ret

empty2 endp

STACKFRAME

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

PROCALIGN

empty3 proc

    ret

empty3 endp

STACKFRAME

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

SET_STACK_FRAME 2, 2

empty4 proc

    ret

empty4 endp

STACKFRAME

; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
    end

Which disassembles to,

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

.text:0000000140001008 49C7C104000000             mov r9, 4
.text:000000014000100f 49C7C003000000             mov r8, 3
.text:0000000140001016 48C7C202000000             mov rdx, 2
.text:000000014000101d 48C7C101000000             mov rcx, 0x1
.text:0000000140001024 E863000000                 call sub_14000108c
.text:0000000140001024
.text:0000000140001029 49C7C104000000             mov r9, 4
.text:0000000140001030 49C7C003000000             mov r8, 3
.text:0000000140001037 48C7C202000000             mov rdx, 2
.text:000000014000103e 48C7C101000000             mov rcx, 0x1
.text:0000000140001045 E84C000000                 call 0x140001096
.text:0000000140001045
.text:000000014000104a 49C7C104000000             mov r9, 4
.text:0000000140001051 49C7C003000000             mov r8, 3
.text:0000000140001058 48C7C202000000             mov rdx, 2
.text:000000014000105f 48C7C101000000             mov rcx, 0x1
.text:0000000140001066 E82C000000                 call sub_140001097
.text:0000000140001066
.text:000000014000106b 49C7C104000000             mov r9, 4
.text:0000000140001072 49C7C003000000             mov r8, 3
.text:0000000140001079 48C7C202000000             mov rdx, 2
.text:0000000140001080 48C7C101000000             mov rcx, 0x1
.text:0000000140001087 E814000000                 call 0x1400010a0
.text:0000000140001087
; --------------------------------------------------------------------------
; sub_14000108c
; --------------------------------------------------------------------------
sub_14000108c   proc
.text:000000014000108c 55                         push rbp
.text:000000014000108d 488BEC                     mov rbp, rsp
.text:0000000140001090 4883EC60                   sub rsp, 0x60
.text:0000000140001094 C9                         leave
.text:0000000140001095 C3                         ret
sub_14000108c   endp

.text:0000000140001096
.text:0000000140001096 0x140001096:
.text:0000000140001096 C3                         ret
; --------------------------------------------------------------------------
; sub_140001097
; --------------------------------------------------------------------------
sub_140001097   proc
.text:0000000140001097 4883EC08                   sub rsp, 8
.text:000000014000109b 4883C408                   add rsp, 8
.text:000000014000109f C3                         ret
sub_140001097   endp

.text:00000001400010a0
.text:00000001400010a0 0x1400010a0:
.text:00000001400010a0 55                         push rbp
.text:00000001400010a1 488BEC                     mov rbp, rsp
.text:00000001400010a4 4883EC60                   sub rsp, 0x60
.text:00000001400010a8 488BE5                     mov rsp, rbp
.text:00000001400010ab 5D                         pop rbp
.text:00000001400010ac C3                         ret
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 08, 2021, 04:36:00 AM
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
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 08, 2021, 05:06:37 AM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: TimoVJL on March 08, 2021, 08:22:52 AM
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:
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: HSE on March 08, 2021, 09:05:45 AM
Hi Nidud!

Quote from: nidud on March 08, 2021, 05:06:37 AMoption 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? 
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 08, 2021, 09:35:30 AM
 :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.

Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: nidud on March 08, 2021, 10:28:24 AM
deleted
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: HSE on March 08, 2021, 12:46:46 PM
Quote from: nidud link=topic=9218.msg101372#msg101372If you add a call at top it make more sense
Ok. Could be necesary sometimes.

Thanks  :thumbsup:
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: daydreamer on March 08, 2021, 06:04:37 PM
Quote from: hutch-- on March 08, 2021, 09:35:30 AM
: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.
I am more interested in link option lower stack space,so i get small memory footprint even with lots of threads,what's good set it,10k?,100k?
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: TimoVJL on March 08, 2021, 06:36:58 PM
I think, only when someone needs more stack than 1MB, -stack option is usable.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: hutch-- on March 08, 2021, 08:01:16 PM
Hi Timo,

> 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

I think I understand why you would have this view but its the nature of the beast as a macro assembler to be able to do stuff like that. In a large number of instances macros are used to reduce the level of tedium hacking through mountains of high level code and funny enough you rarely ever see macro code in pure mnemonic algorithms. Where the grunt really matters, pure mnemonic code rules.

The problem with late model Window UI code is that it is cluttered and complicated by way of its original design and even with great patience it can be messy to read.
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: daydreamer on March 08, 2021, 10:08:33 PM
Quote from: hutch-- on March 08, 2021, 08:01:16 PM
> 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

I think I understand why you would have this view but its the nature of the beast as a macro assembler to be able to do stuff like that. In a large number of instances macros are used to reduce the level of tedium hacking through mountains of high level code and funny enough you rarely ever see macro code in pure mnemonic algorithms. Where the grunt really matters, pure mnemonic code rules.
I like the right kind of macros help with code productivity for whole asm program and concentrate on optimization where it matters
where real grunt the big exception using Macros for later SSE opcodes,128bit SIMD integer xmm regs instead of only 64bit registers
you could have 2048 threads * stack 1mb on 64bit,but its useless for those who have old 32bit computer with not so much memory,so if I only use few small LOCAL arrays it might be only need 10k or 100k stack?
Title: Re: 64-bit: Why Can't I get "CreateFileA" to Access a File or Device?
Post by: jj2007 on March 08, 2021, 10:27:54 PM
Quote from: TimoVJL on March 08, 2021, 06:36:58 PM
I think, only when someone needs more stack than 1MB, -stack option is usable.

It seems so. For example, with linker option /STACK:0xF00000 you get 20MB instead of 1.x, but I have not been able to get less than 850k (in 32-bit code).