Hello you all, I'll be brief since I don't have much time. I'm currently coding procedures in assembly that will will be called from a C++ program. I'm am very concerned with learning every single aspect and doing it the most efficient way, and I hope you guys can help me with some questions that I couldn't find answers for by looking on the internet. I'll be posting each procedure and what my questions are for the same project here so I don't spam.
Proceure I'm working on right now: I get the adress of two strings and then add the second string to the end of the first one
Code:
QuoteStrCatAsm PROC uses ecx edi eax, ;save registers used
str1Add:DWORD, ;address of string1
str2Add:DWORD, ;address of string2
;Get length of string
mov ecx,MAX_LEN ;populate ecx with max length for string
mov edi,str2Add ;edi gets destination address for searching string size
mov eax,0 ;Populate eax with 0
cld ;forward direction - clear direction flag
repne scasb ;drecrements ecx until 0 termination is found in string
not ecx ;Two's complement to convert difference to a positive value
;I initially subtracted max_len from ecx to get the difference in a negative value
;and then inverted the sign, but observing the register I realized that not was an alternative
;Concatenate to the end of other string
mov edi,str1Add ;edi gets destination address for copy
mov esi,str2Add ;esi gets source address for copy
push ecx ;save ecx
mov ecx,MAX_LEN ;store max_length in ecx
cld ;forward direction - clear direction flag
repne scasb
pop ecx ;restore ecx
dec edi ;overwrite 0 from string1
rep movsb ;copy byte from source to desintation ecx times
ret
This code works the way it is right now, but I was trying to make it more efficient by getting the length of string2 using the value of the adresses. I noticed that that: length = (strAdd1 - strAdd2)/2 . Is there a way I can calculate this on a local variable instead of arguments and register? Something like localVar equ (strAdd1 - strAdd2)/2 . Thanks
Quote from: MrIteration on December 02, 2011, 11:11:02 PM
I noticed that that: length = (strAdd1 - strAdd2)/2.
That doesn't make sense. Explain.
QuoteIs there a way I can calculate this on a local variable instead of arguments and register? Something like localVar equ (strAdd1 - strAdd2)/2.
With Masm32 installed, you would simply use
StrCatAsm PROC ...
LOCAL slen
mov esi, straddress
mov slen, len(esi)
or something similar. Much faster than repne scasb, by the way...
There are a number of assumptions involved, one is that you can know the string lengths prior to calling the algorithm, the other is that the buffer size for the first string is large enough to hold the extra data.
if you can know the lengths of both strings and specify the buffer size for the first to be long enough to take both, then you write an algo that has 4 arguments, the two string addresses and the length of at least the first string and better to have the length of both.
If alternately you want the simple format of just passing the two addresses then you need to scan the first string to find the end of it. Depending on the string lengths you have in mind, strings under about 500 bytes are best done with incremented pointers, over that length REP MOVSB/D combinations are generally faster. Unless your strings are into the megabyte range a very short incremented pointer version will be easily fast enough. If you are working on very large text (multi-megabyte) then an SSE version will give you some advantage in terms of speed.