The szCatStr return a useless information who is the start of the chain.
A usefull information to return is the adress of the chain written,this allow repeated call to the function (what is often the case) without losing time scanning and re-scanning the start of the chain.
Here is the modify function.
Sample:
invoke lstrcpy,addr big,addr string
invoke modszCatStr,addr big,addr str1
invoke modszCatStr,eax,addr string ;save time here
invoke MessageBox,NULL,addr big,ADDR string,MB_OK
Quote
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 16
modszCatStr proc lpszSource:DWORD, lpszAdd:DWORD
push edi
mov edi, [esp+8]
.if byte ptr [edi] != 0
invoke fastlstrlen,[esp+8] ; get source length
add edi, eax ; set write starting position
.endif
mov ecx, [esp+12]
xor edx, edx ; zero index
@@:
movzx eax, BYTE PTR [ecx+edx] ; write append string to end of source
mov [edi+edx], al
add edx, 1
test eax, eax ; exit when terminator is written
jne @B
dec edx
lea eax,[edi+edx] ; return address end chain
pop edi ; useful for a new call,save time
ret 8
modszCatStr endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
; «««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««««
Yves,
That is why there are a number of string functions that do similar things.
If you are performing repeat append operations.
szappend proc string:DWORD,buffer:DWORD,location:DWORD
If you wish to join a list of strings in one operation.
szMultiCat proc C pcount:DWORD,lpBuffer:DWORD,args:VARARG
Hi Yves,
You wrote :
QuoteThe szCatStr return a useless information who is the start of the chain.
The Masm32 library reference :
QuoteReturn Value
There is no return value.
Quote
The Masm32 library reference say there is no return value
The Masm32 library reference is wrong
Quote
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
align 16
szCatStr proc lpszSource:DWORD, lpszAdd:DWORD
push edi
invoke szLen,[esp+8] ; get source length
mov edi, [esp+8]
mov ecx, [esp+12]
add edi, eax ; set write starting position
xor edx, edx ; zero index
@@:
movzx eax, BYTE PTR [ecx+edx] ; write append string to end of source
mov [edi+edx], al
add edx, 1
test eax, eax ; exit when terminator is written
jne @B
pop edi
mov eax, [esp+8] ; return start address of source
ret 8
szCatStr endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
Yves,
You have failed to understand the algo design, setting EAX to the start address allows the procedure to be used as a function. A number of algos in the masm32 library do this so that they are easier to use with macros. The algo can just as easily be used by storing the start address elsewhere and not using the value in EAX.
The notion of a return value implies that something else is returned in EAX, the help file is correct here, there is no return value as EAX has the start address returned for convenience in constructing macros.
philosophical answer.
eax is modified just before the ret with this remark
Quote
return start address of source
Seems I am not the only one to not understand your reason to say it's not a return value.
Elsewhere , If it is needed for some macro ,he is useful.
I prefered the end of chain returned.
Sorry this message is misplaced here.
GOOD NEWS ,THIS WORK STRUCT align = DWORD,QWORD....
Quote
aSTORAGE_PROPERTY_QUERY STRUCT DWORD
PropertyId DWORD ?
QueryType DWORD ?
AdditionalParameters BYTE 1 dup(?) ; dup (?)
aSTORAGE_PROPERTY_QUERY ENDS
The three append procedures work like this.
IF 0 ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
Build this template with "CONSOLE ASSEMBLE AND LINK"
ENDIF ; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
include \masm32\include\masm32rt.inc
.code
start:
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
call main
inkey
exit
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL pbuf :DWORD ; allocate a pointer
LOCAL buffer[260]:BYTE ; allocate a buffer
LOCAL cloc :DWORD ; location pointer
LOCAL wrds1 :DWORD
LOCAL wrds2 :DWORD
LOCAL wrds3 :DWORD
LOCAL wrds4 :DWORD
LOCAL wrds5 :DWORD
LOCAL wrds6 :DWORD
mov wrds1, chr$("one ")
mov wrds2, chr$("two ")
mov wrds3, chr$("three ")
mov wrds4, chr$("four ")
mov wrds5, chr$("five ")
mov wrds6, chr$("six ")
; -------------
; simple append
; -------------
mov pbuf, ptr$(buffer) ; set pointer to buffer address
fn szCopy,wrds1,pbuf
fn szCatStr,pbuf,wrds2
fn szCatStr,pbuf,wrds3
fn szCatStr,pbuf,wrds4
fn szCatStr,pbuf,wrds5
fn szCatStr,pbuf,wrds6
print pbuf,13,10
; -----------------
; sequential append
; -----------------
mov pbuf, ptr$(buffer) ; set pointer to buffer address
mov cloc, 0
mov cloc, rv(szappend,pbuf,wrds1,cloc)
mov cloc, rv(szappend,pbuf,wrds2,cloc)
mov cloc, rv(szappend,pbuf,wrds3,cloc)
mov cloc, rv(szappend,pbuf,wrds4,cloc)
mov cloc, rv(szappend,pbuf,wrds5,cloc)
mov cloc, rv(szappend,pbuf,wrds6,cloc)
print pbuf,13,10
; ---------------
; combined append
; ---------------
mov pbuf, ptr$(buffer) ; set pointer to buffer address
fn szMultiCat,6,pbuf,wrds1,wrds2,wrds3,wrds4,wrds5,wrds6
print pbuf,13,10
ret
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end start