troubleshooting Question

cmp [esi], [edi] ?

Avatar of Sandra-24
Sandra-24 asked on
Assembly
6 Comments1 Solution4309 ViewsLast Modified:
The compiler doesn't like the line: cmp [edi], [esi], "bad operand type"

Why?

Also would you have a look at what I'm doing with the compare loop (and the reason I am trying to do the above cmp) and see if you can think of a better way of doing it. Keep in mind this hasn't been run yet so there may be bugs (my first assembly program of > 3 lines :).

void * __cdecl memmem(const void * buf, size_type count, const void * needle, size_type needle_len)
{
      __asm
      {
            pop            ebx                                    ;// Put needle length in ebx register
            pop            edi                                    ;// Put buffer in destination register
            pop            ecx                                    ;// Put count in ecx register
            pop            esi                                    ;// Put needle in source register

            test      ebx, ebx                        ;// Is needle empty?
            jz            found                              ;// Return buffer

            xor            edx, edx                        ;//      Clear edx, because we may use the whole thing later (in to_memchr)

            mov            dl, [edi]                        ;// Put first byte of needle into dl (we know it has atleast 1 byte

            cmp            ebx, 2                              ;// Is needle atleast 2 bytes?
            jb            to_memchr                        ;// Needle length is one byte, call memchr instead

            mov            dh, [edi+1]                        ;// Put second byte in dh
            sub            ebx, 2                              ;// Subtract two from needle length (since we have two bytes of it in registers already)

            jmp            main_loop                        ;// Needle is greater than or equal to 2 bytes

cmp_next_byte:
            cmp            [edi], dl                        ;// Compare first byte of needle with byte of buffer
            je            get_second_byte                  ;// Match, check the rest of needle against the rest of buffer

            jmp            main_loop                        ;// Back to main loop

get_second_byte:
            sub            ecx, 1                              ;// Decrement counter
            jb            not_found                        ;// Counter went below zero, needle wasn't found

            add            edi, 1                              ;// Increment buffer pointer
            cmp            [edi], dh                        ;// Check if second byte matches
            je            compare_init                  ;// Match, compare rest of needle against buffer

            jmp            cmp_next_byte                  ;// We've fetched the next byte, decremented the counter, just continue on as normal, comparing it with the start of the pattern

compare_init:
            cmp            ecx,ebx                              ;// ebx must be greater than or equal to length of needle - 2
            jb            not_found                        ;// If count is < needle length, needle cannot be in the buffer

            mov            eax, ebx                        ;// Take a new copy of needle length for use as a counter

            push      edi                                    ;// Preserve buffer pointer
            push      esi                                    ;// Preserve needle

            jmp            compare_loop                  ;// Loop

compare_cleanup:
            pop            esi                                    ;// Restore needle
            pop            edi                                    ;// Restore buffer

            jmp            main_loop                        ;// Continue looking

main_loop:
            sub            ecx, 1                              ;// Decrement counter
            jb            not_found                        ;// Counter went below zero, needle wasn't found

            add            edi, 1                              ;// Increment buffer pointer

            jmp            cmp_next_byte                  ;// Compare this byte of the buffer against dl

compare_loop:
            test      eax, eax                        ;// Zero, we're compared this byte already, we've found it!
            jz            found

            cmp            [edi], [esi]                  ;// Compare last character
            jne            compare_cleanup                  ;// No match, keep looking

            sub            eax, 1                              ;// Decrement counter (checked on next iteration for zero)
            sub            edi, 1                              ;// Get previous byte
            sub            esi, 1                              ;// Get previous byte

            jmp            compare_loop                  ;// So far, so good, keep checking the needle against the buffer

found:
            mov            eax, edi                        ;// Return current location in buffer
            ret

not_found:
            xor            eax, eax                        ;// Return zero
            ret

to_memchr:
            push      ecx                                    ;// Count
            push      edx                                    ;// Push needle (must be passed as an int)
            push      edi                                    ;// Buffer
            call      memchr                              ;// Call memchr(buffer,value,count)
            ret                                           ;// Return memchr's return value
      }
}

Thanks for your time!

This is actually the code of a colleague of mine, I'm just trying to help him get it working, he's an assembly novice also. He's been talking about posting it to code project when it's all finished, so you could look for the final version there later, if you are interested.
Join the community to see this answer!
Join our exclusive community to see this answer & millions of others.
Unlock 1 Answer and 6 Comments.
Join the Community
Learn from the best

Network and collaborate with thousands of CTOs, CISOs, and IT Pros rooting for you and your success.

Andrew Hancock - VMware vExpert
See if this solution works for you by signing up for a 7 day free trial.
Unlock 1 Answer and 6 Comments.
Try for 7 days

”The time we save is the biggest benefit of E-E to our team. What could take multiple guys 2 hours or more each to find is accessed in around 15 minutes on Experts Exchange.

-Mike Kapnisakis, Warner Bros