Assembly lang hw help

My teacher gave us this small assignment to do and i just have no clue where to start,

We have this C code
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-165 ICE#8 Bochsler\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 have to write the asm that does this

- take two char * arguments via the stack
- implements a C calling interface and follows the C calling conventions
- implements the following logic:
bool isStringEqual(const char *s1, const char * s2)
{
while (*s1 != 0 && *s2 != 0) {
if (*s1 != *s2)
return false;
}
return true
}

Weve done things with C and asm before but compared numbers together and figured out which is the longest. I understand how to do the while loops but i have no fucking clue what is going on in that C code, I dont understand how to get the strings and compare them. If i could get some help figuring out how to compare the strings i am sure i could do the while loop.

I tried something like this:
PUSH ebp ; save caller base pointer
MOV ebp, esp ; set our base pointer
PUSH edi
PUSH esi
MOV eax, [ebp + 8]
MOV ebx, [ebp + 12]

top:
CMP eax,0
CMP eax, ebx ; check loop condition
JAE next ; false? exit loop
; loop body
INC eax ; adjust condition
JMP top ; repeat the loop

next:
PUSH OFFSET fmt ; push the string format
ADD esp, (2 * 4) ; clear the stack

then deallocate and restore pointers but nothing is working,

Other urls found in this thread:

en.wikipedia.org/wiki/X86_calling_conventions
twitter.com/AnonBabble

are you still around? i can take a look...

yeah Im still around
posted to stack overflow and im still not understanding shit. how would you like to take a look?

I did x86 assembly last semester, but im too stupid to remember everything properly. I do know that your comparison seems wrong...

Alright, a few things:

you are moving the first character of first string into eax, first character of second string into ebx, then you start the loop

in the loop, you compare the first character to 0, then you compare it to second character, overwriting your first comparison.

you jump to false if the character in eax is bigger than or equal to character in ebx, which seems wrong already, as you should be comparing equality

then if you dont jump, you increment eax, as in, you add 1 to the ascii value of the character, which is not what you are meaning to do.

I wrote up a new comparison, S.O said i need t deference s1 and s2, and use them since there already in edi and esi
here is what i have now...
its probably still wrong however if i make
eax a 0 they all return false

MOV eax, -1
top:
CMP esi, 0 ; while s1 !=0
JNE next ;keep going, if not then return false
CMP edi, 0 ; while s2 != 0
JNE next ;keep going, if not then return false
CMP edi, esi ;if s1 != s2
JNE next
INC eax ; adjust condition
JMP top ; repeat the loop


next:
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

I made a new comparison, here is this any better....

Uhh you seem to be doing unnecessary checks.
Also I honestly don't remember which way the stack goes so I don't know if the way you are getting the string addresses is correct, but also I'm not sure you are meant to deallocate the local strings. Honestly there's so much I don't remember, including cdecl and stdcall calling conventions, but I did write this:

push ebp
mov ebp, esp
push edi
push esi
mov esi, [ebp+8]
mov edi, [ebp+12]

mov ebx, 0
str_cmp_loop:
mov al, [esi+ebx]
cmp al, [edi+ebx]
jne str_ret_false
cmp al, 0
je str_ret_true
inc ebx
jmp str_cmp_loop

I think that the top portion is correct.
Naturally you have to add a label to the top of that in order for the subroutine to be called, and you must add the str_ret_false and str_ret_true labels and code in order for you to properly fix the stack and return a value.

I'm really uncertain in myself since A. I'm known to be retarded and B. my university's server is down and I cant test.

So look at the code I wrote here:
You increment eax but that doesn't actually do anything for your comparisons. You keep comparing esi and edi, but those should only contain addresses to the two strings. Ideally you should be using them, with eax as an offset, to retrieve the ascii characters in each string and compare, as I do in the lines
mov al, [esi+ebx]
cmp al, [edi+ebx]
I also use al since ascii values are only a byte in size and this way i can guarentee there's nothing in the upper 3 bytes of eax or something silly like that. Try my code, let me know how it works out...

I should also mention that all the shit you push to the stack in the beginning should be properly popped and restored to the original registers, otherwise I think that behavior is not guaranteed.

im a little confused on jmp str_cmp_false and jmp str_cmp_true, they go to nowhere....

Sorry Im a new form of retarded.

those push's are paired with the pops at the end though i think...

I said in the post above:
"you have to add a label to the top of that in order for the subroutine to be called, and you must add the str_ret_false and str_ret_true labels and code in order for you to properly fix the stack and return a value."
I'm reading up on it again to make sure you are properly restoring state at the end. Are you using the __cdecl calling convention?

no im not using __cdecl

Ok, then I'm not familiar with the calling convention. What are you using?

....I honestly dont really know what "__cdecl " is it just tells the compiler what to push when right? because it might not be C code?


i believe thats what the
extern "C" {.... is doing in the beginning.

the only thing else have else is


#include
#include
#include
#include "ICE7.h"

the asm is in a static library which is referenced to the cpp.

Listen, I have no idea. I only learned __cdecl and how it's used, but I think different conventions work a little differently in how arguments are pushed and which registers have to be preserved. The extern portion is supposed to tell your program not to freak out when the function is invoked and that it exists outside the scope of the file or something. I have zero clue as to what it means for something to be "in a static library".
It's 5 am here and I'm tired as fuck so idk if I'm in any state to help. I think that the actual string comparison I posted is correct, so as long as you get the strings and are able to restore state at the end, you can probably use what I provided.
Here's the wikipedia article on calling conventions, make sure you conform to them I guess and know which one you are using:
en.wikipedia.org/wiki/X86_calling_conventions

No worries and thank you, I really appreciate every single bit. especially since you had to deal with my retardation. I used what you wrote up added a few things and my output looks almost the same as his just the opposite so at least I'm making some progress.

Thanks again I fucking owe you

When I wake up in 3 hours to go to work, I'll check back here in case you have any problems or in case you get it working so keep posting if you don't mind...

Can i give you my email? ill probably forget and this thread will probably time out or something.

actually fuck it ill keep posting updates so it doesn;t die

Bump

if anyone else is checking in this is what i have and i have no fucking idea what to du. and im tired as shit

it outputs false false true but is supposed to be true true false.

printf PROTO C, :VARARG

.DATA ; declare initialzed data here
fmt db "%d", 10, 0

.STACK ; use default 1k stack space

.CODE ; contains our code
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]
CMP al, [edi + ebx]
JNE str_ret_false
CMP al, 0
JE str_ret_true ;if al =0 jump -> true
INC ebx ;inc and do loop again
JMP str_cmp_loop

str_ret_false:
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 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

im so close to just saying fuck it and submitting whats here. someone please save me....

LMFAO dude...

str_ret_false:
MOV eax, 0
JMP str_ret
str_ret_false:
MOV eax, 0
str_ret:
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

try this my friend

THIS works because the return value is stored in eax register, it says false false because al (eax) has 0 in it if the two strings are equal, and something else in it (usually) when the two strings aren't. You could probably rewrite this in such a way that the loop guarantees that behavior, but it's easier to replace what you have after the loop with this.

OP try this shit so I can die in peace please

if i replace it i get an error it doesn't know wtf str_ret_true is .... but hold up

Shit dude i mistyped but do i have to do everything?

printf PROTO C, :VARARG

.DATA ; declare initialzed data here
fmt db "%d", 10, 0

.STACK ; use default 1k stack space

.CODE ; contains our code
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]
CMP al, [edi + ebx]
JNE str_ret_false
CMP al, 0
JE str_ret_true ;if al =0 jump -> true
INC ebx ;inc and do loop again
JMP str_cmp_loop

str_ret_false:
MOV eax, 0
JMP str_ret
str_ret_true:
MOV eax, 1
str_ret:
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

Please tell me if this works quick im so sleepy dude

only if i can die first

it works jesus crist fuckin thank you..
sorry im fucking stupid...

its ok bro it was my fault too
that said did you miss lecture or some shit??

im gonna rewrite it and make notes so i can understand it fucking thank you.

OH SHIT THAT MAKES SENSE

he just goes by incredibly fast in lecture,he skips alot of slides and im pretty retarded plus vision disability so i cant even see what he puts on the board
Ive just now been starting to understand everything halfway through the semester. otherwise ive been scrapping by.

this is making more sense as i re write it though

logging off and thank you, email my backup email: [email protected] i want to repay you for helping me learn this shit in some way.

You can get the asm code with a compiler just copy it and modify it a bit