Archived

This topic is now archived and is closed to further replies.

another go.. why does this work?

This topic is 5333 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Is this valid? *PTR++ is pointing to a QWORD, if all of 8 bytes is 0 then it is 0, correct? Why is this working, returning valid lengths, and not crashing or returning wrong values on nonaligned boundaries? According to everybody, I should be getting off-values or crashing but not so I tell ya... I''m using dev-cpp btw.. -O3 does result in speed increase of 40-90% testing against the regular strlen() function.. tested on a char buff[5000] with 4999 filled in with ''*'', and a char *buff2 = new char [15000] with 3817 bytes copied to it for testing, I even varied the counts around, 3816, 3818,3819 testing the qword alignment.
  
extern "C" int StrLen(void *);

               ...and...

int StrLenA(const void * cha) {

    unsigned int retg=-sizeof(unsigned long long);
// back retg up a bit for accuracy..

    unsigned long long *ptr;
    unsigned char *chr;

    ptr = (unsigned long long *) cha;
    chr = (unsigned char *) cha;

    for (;*ptr++;retg+=sizeof(unsigned long long));
    for (;chr[retg];retg++);

    return(retg);
}  
DEBUGGER:
  
************ QWORD for(;;;) *************************
00402395  |> 8B51 04        /MOV EDX,DWORD PTR DS:[ECX+4]
00402398  |. 8B01           |MOV EAX,DWORD PTR DS:[ECX]
0040239A  |. 89D7           |MOV EDI,EDX
0040239C  |. 83C3 08        |ADD EBX,8
0040239F  |. 83C1 08        |ADD ECX,8
004023A2  |. 09C7           |OR EDI,EAX
004023A4  |.^75 EF          \JNZ SHORT Project1.00402395

************ BYTE for(;;;)  ***************************
004023B0  |> 43             /INC EBX
004023B1  |. 803C33 00      |CMP BYTE PTR DS:[EBX+ESI],0
004023B5  |.^75 F9          \JNZ SHORT Project1.004023B0
  
I fseek, therefore I fam.

Share this post


Link to post
Share on other sites
ok, I think I see what is going on.. if the buffer isn''t at least 8 bytes larger than the actual string, it returns an error cause ptr is looking at every 8 bytes..

I fseek, therefore I fam.

Share this post


Link to post
Share on other sites
next question: is there some sort of bit-shifting algo to see if I am hitting the end of the buffer or not.. eg:

char buff[11]="1111111111"; // strlen() = 10
- returns erroneous value - 17

char buff[17]="1111111111"; // strlen() = 10
- returns perfect value - 10

I fseek, therefore I fam.

[edited by - drarem on May 5, 2003 8:55:45 PM]

Share this post


Link to post
Share on other sites
quote:
next question: is there some sort of bit-shifting algo to see if I am hitting the end of the buffer or not.. eg:

Yes, 8 bytes of 0

It''s probably working for the second case because it''s trying to allocate memory in a multiple or 4 (maybe), so in reality you have 20 bytes. That leaves 11 for the string, plus 9 uninitialized which is just over 8 zero bytes to end at. If you only allocate 11 bytes, it really gets 12 (I''m just speculating), and that''s not enough "extra" bytes for there to be an end-string delimitation.

Share this post


Link to post
Share on other sites
Alllrighty, here we go... this works perfectly, adds in qwords and tests for buffer border.. only problem is, how do I speed this up? Isn''t there a way to test a byte against a value to test for 0''s in it, like AND x80808080h or something?


  int StrLenA(const void * cha) {
bool cont=TRUE;
signed int retg=-sizeof(unsigned long long);
unsigned long long *ptr;
unsigned char *chr;
ptr = (unsigned long long *) cha;
chr = (unsigned char *) cha;

for (;cont;) {
*ptr++; retg+=sizeof(unsigned long long);
if (!(1 & *ptr)) cont=FALSE;
if (!(2 & *ptr)) cont=FALSE;
if (!(4 & *ptr)) cont=FALSE;
if (!(8 & *ptr)) cont=FALSE;
}

// multiply retg back out, switching to char sizes now..

retg = retg >> 4; //should be #define''d as 4

for (;chr[retg];retg++);
return(retg);
}




I fseek, therefore I fam.

Share this post


Link to post
Share on other sites
quote:
Original post by drarem
Isn''t there a way to test a byte against a value to test for 0''s in it, like AND x80808080h or something?

Look here (search for "fstrlen" within the page). It uses ints, but you shouldn''t have any problems implementing the same thing for long longs.

Share this post


Link to post
Share on other sites