News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

How to Call StringCchCat in Win64 Assembly?

Started by wanker742126, October 30, 2024, 07:30:05 PM

Previous topic - Next topic

sinsi

Quote from: zedd151 on November 01, 2024, 04:51:19 AMMy critique was only a suggestion.
Hey, I didn't even consider it a critique, just a statement :biggrin:

NoCforMe

In my not-so-humble opinion, nearly all of the string functions ought to be written by the programmer as learning exercises, rather than relying on canned library functions. At least that's what I've done (in 32-bit code):
  • strlen()
  • strcpy()
  • strcat
  • strcmp()
This covers probably 95% of what actually gets used, and these are not at all difficult to write.

If you need fast routines, you can either optimize these yourself or search this site for the mo-fasta code that people have written. But usually string manipulation is not something where speed really matters.
Assembly language programming should be fun. That's why I do it.

wanker742126

Returning to my original question, I'd like to ask about the code for StringCchCatA in strsafe.h:

STRSAFEAPI
    StringCchCatA(
            _Inout_updates_(cchDest) _Always_(_Post_z_) STRSAFE_LPSTR pszDest,
            _In_ size_t cchDest,
            _In_ STRSAFE_LPCSTR pszSrc)
{
    HRESULT hr;
    size_t cchDestLength;

    hr = StringValidateDestAndLengthA(pszDest,
            cchDest,
            &cchDestLength,
            STRSAFE_MAX_CCH);

    if (SUCCEEDED(hr))
    {
        hr = StringCopyWorkerA(pszDest + cchDestLength,
                cchDest - cchDestLength,
                NULL,
                pszSrc,
                STRSAFE_MAX_LENGTH);
    }

    return hr;
}

If I were to rewrite this in assembly language, would it look something like this?

StringCchCatA PROC pszDest:QWORD,cchDest:DWORD,pszSrc:QWORD
        LOCAL   cchDestLength:DWORD
        invoke  StringValidateDestAndLengthA,pszDest,cchDest,ADDR cchDestLength,STRSAFE_MAX_CCH
        cmp     eax,0
        jl      exit
        sub     r10,r10
        mov     r10d,cchDestLength
        mov     rcx,pszDest
        add     rcx,r10
        mov     edx,cchDest
        sub     edx,cchDestLength
        invoke  StringCopyWorkerA,rcx,edx,0,pszSrc,STRSAFE_MAX_LENGTH
exit:   ret
StringCchCatA ENDP

If there are any mistakes, please let me know.

NoCforMe

        invoke  StringValidateDestAndLengthA,pszDest,cchDest,ADDR cchDestLength,STRSAFE_MAX_CCH
        cmp    eax,0
        jl      exit

Pretty sure the return value from a Windows function will never be negative. All unsigned values.
Assembly language programming should be fun. That's why I do it.

sinsi

Quote from: NoCforMe on November 01, 2024, 07:06:43 PMPretty sure the return value from a Windows function will never be negative. All unsigned values.
The function (like a lot of others) returns a HRESULT.

Quote from: WikipediaHRESULT is defined in a system header file as a 32-bit, signed integer
Usually the high bit set signifies an error.
QuoteBit 31: S - Severity - indicates success (0) or failure (1)

TimoVJL

#if !defined(_HRESULT_DEFINED) && !defined(__midl)
#define _HRESULT_DEFINED
typedef long HRESULT;
#endif /* _HRESULT_DEFINED */

FORCEINLINE HRESULT HRESULT_FROM_WIN32(unsigned long x) {
    return (HRESULT)(x) <= 0 ? (HRESULT)(x) : (HRESULT)(((x) & 0x0000FFFF) | (FACILITY_WIN32 << 16) | 0x80000000);
}
in strsafe.h#ifndef _HRESULT_DEFINED
#define _HRESULT_DEFINED
typedef long HRESULT;
#endif /* _HRESULT_DEFINED */

typedef unsigned long DWORD;

#define SUCCEEDED(hr)  (((HRESULT)(hr)) >= 0)
#define FAILED(hr)     (((HRESULT)(hr)) < 0)

#define S_OK  ((HRESULT)0L)

May the source be with you

NoCforMe

Quote from: sinsi on November 01, 2024, 08:12:27 PMUsually the high bit set signifies an error.
QuoteBit 31: S - Severity - indicates success (0) or failure (1)

Ah so. Thanks. I stand (sit) corrected.
Assembly language programming should be fun. That's why I do it.