3

for a small assignment we have to compare strings we were given this code in C

extern "C" {
    bool isStringEqual(const char *s1, const char *s2);
}

static char *testStrings[] = {
    "",
    "Test String 1",
    "Test String 2",
};
#define NUM_TEST_CASES  (sizeof (testStrings) / sizeof (char *))

int main()
{
    printf("CSIS\n\n");

    for (int i = 0; i < NUM_TEST_CASES; i++) {
        printf("Input string [%s] [%s] yields: %s\n ", testStrings[i], testStrings[i],
            isStringEqual(testStrings[i], testStrings[i]) ? "true" : "false");
    }

    printf("Input string [%s] [%s] yields: %s\n ", testStrings[1], testStrings[2],
        isStringEqual(testStrings[1], testStrings[2]) ? "true" : "false");

    system("PAUSE");

    return 0;
}

and we have to write the asm that does this logic

;           while (*s1 != 0 && *s2 != 0) {
;               if (*s1 != *s2)
;               return false;
;           }
;           return true

Previously what we did before was we compared numbers which were input in C and then did some comparisons and calculations in asm. That was fine and I understood those completely, what I am having trouble here is understanding the C given and what are the strings (they seem to both look like "i" to me or possibly 1 and 2??) . And the second thing is finding out how I can compare the two strings. I understand how jumps and comparisons work and can make loops just fine just dont know how to go about comparing the strings...

Here is my asm that runs but will make everything still print out as

input

 Input string [Test String 1] [Test String 1] yields: true
 Input string [Test String 2] [Test String 2] yields: true
 Input string [Test String 1] [Test String 2] yields: true
 Press any key to continue . . .

My asm:

isStringEqual PROC PUBLIC
    PUSH    ebp             ; save caller base pointer
    MOV     ebp, esp        ; set our base pointer
    PUSH    edi
    PUSH    esi             


;--------------------------------------------------------
;           while (*s1 != 0 && *s2 != 0) {
;               if (*s1 != *s2)
;               return false;
;           }
;           return true
;-----------------------------------------------------------  
  mov esi, [ebp+8]              ;get s1
    mov edi, [ebp+12]               ;get s2

    MOV ebx, 0                      ;move 0 into ebx
str_cmp_loop:
MOV al, [esi + ebx]             ;goes right to left for string
CMP al, [edi + ebx]             ;compares 
JNE str_ret_false
CMP al, 0
JE str_ret_true
INC ebx
JMP str_cmp_loop

str_ret_false:

PUSH eax
PUSH OFFSET fmt         ; push the string format
ADD esp, (2 * 4)        ; clear the stack
POP esi 
POP edi
MOV esp, ebp            ; deallocate locals
POP ebp              ; restore caller base pointer
RET

str_ret_true:

PUSH eax
PUSH OFFSET fmt         ; push the string format
ADD esp, (2 * 4)        ; clear the stack
POP esi 
POP edi
MOV esp, ebp            ; deallocate locals
POP ebp                  ; restore caller base pointer
RET
isStringEqual ENDP  ; end the procedure
END isStringEqual

Can someone please just help me so I can go to sleep...

Ryan
  • 433
  • 3
  • 8
  • 14
  • are you comparing the pointers, instead of their content? – Tommylee2k Mar 24 '17 at 07:32
  • I believe i am comparing their content but in asm I would be comparing their pointers – Ryan Mar 24 '17 at 07:37
  • what's pushed is s1 and s2, you need to dereference them ( you already "save" ESI and EDI ... it would be a good idea to use them ;) ) – Tommylee2k Mar 24 '17 at 07:41
  • A few problems: 1) Doing 2 `cmp`s in a row is meaningless. The results from the second overwrite the first. As Tommylee2k says, you are comparing the pointers, not the contents (`cmp [eax], 0`). You increment the pointer in `eax` but not `ebx`. There's probably more, but that's where I'd start. – David Wohlferd Mar 24 '17 at 07:43
  • even if i deference them with something like CMP esi, edi i still get the same output.... – Ryan Mar 24 '17 at 08:10
  • your while loop is infinite if the chars are same and not 0. `while (*s1 != 0 && *s2 != 0) { if (*s1 != *s2) return false; }` – AndersK Mar 24 '17 at 08:52
  • `CMP esi` does not dereference any more than `CMP eax` does. It's the brackets (`CMP [esi]` or `CMP [eax]`) that indicate that you want the value stored at that address. Also, when you use `JNE next`, you are saying "if esi is not zero (like if it is 'A'), jump to next." Are you sure that's what you intend? 'next' appears to be the exit, not the "keep going." – David Wohlferd Mar 24 '17 at 09:06
  • @Ryan `CMP esi,edi` still compares the pointers. you have to read the memory they point to – Tommylee2k Mar 24 '17 at 09:16
  • The 'return value' for isStringEqual is whatever is in eax. If your strings are the same, then eax is always going to be 0 (aka false). In the place where you want to return true, set eax to a nonzero value. In the place where you want it to return false, set it it 0. And I really don't understand what you are trying to do with `PUSH eax PUSH OFFSET fmt ADD esp, (2 * 4)`. You push 2 things only the stack, then immediately pop them off? What do you think this is going to do? – David Wohlferd Mar 24 '17 at 12:22
  • Some hints about what can be "string" (just one of possibilities) in assembly: http://stackoverflow.com/questions/40575898/how-to-use-strings-in-emu8086/40580889#40580889 – Ped7g Mar 24 '17 at 16:16

0 Answers0