Im doing this small little assignment and would like some help
Here is what we have to do
; Create an x86 ASM function () which must:
; - implements a C calling interface and following the C calling conventions
; - correctly maintains the program stack
; - implements the following function:
; int32_t findFirstChar(char *cstring, char c);
; - using the string functions as described in this week's lesson, implement a
; function that will return the offset of the first character 'c' in the string
; that is passed in.
; - if the character is not found, return -1.
Here is a C file that has the values passed to asm:
"#include <stdint.h>")
#include <stdio.h>
extern "C" {
int32_t findFirstChar(char *, char);
}
static char *testStrings[] = {
"",
"#",
"abc",
"abcd",
"abdefg",
"ABCdefg",
"bcdefgh",
"abdefabcd",
"abcdefgh",
"abcabcabcda",
};
#define NUM_TEST_CASES (sizeof (testStrings) / sizeof (*testStrings))
static char testChars[] = { 'c', 'd' };
int main()
{
printf("CSIS-165 ICE#12 Bochsler\n\n");
//int f = findFirstChar(testStrings2[2], 'd');
for (int i = 0; i < sizeof(testChars); i++) {
char c = testChars[i];
for (int j = 0; j < NUM_TEST_CASES; j++) {
char *s = testStrings[j];
printf("Char [%c] String [%s] offset [%d]\n", c, s, findFirstChar(s, c));
}
printf("\n");
}
return 0;
}
>>59996747
Here is my asm
".386P ; use 80386 instruction set")
.MODEL flat,C ; use flat memory model
printf PROTO C, :VARARG
.DATA ; declare initialzed data here
target DWORD COUNT DUP(?)
.STACK ; use default 1k stack space
.CODE ; contains our code
stringLength PROC
PUSH ebp ; save caller base pointer
MOV ebp, esp ; set our base pointer
PUSH edi
PUSH esi ; end prologue
MOV esi, [ebp + 8]
MOV eax, 0
;L1:
; MOV bl, BYTE PTR [esi + eax]
; INC eax
; CMP bl, 0h
; JNZ L1
; DEC eax
cld ; clear destination
mov esi, OFFSET BYTE PTR [esi + eax] ;start
mov edi, OFFSET target ;emd
INC ecx
rep movsd ;will inc ecx by 1 a as everything is getting coppied
PUSH ecx ;saves the counter number
POP esi ; start epilogue
POP edi
MOV esp, ebp ; deallocate locals
POP ebp ; restore caller base pointer
RET
stringLength ENDP
;-------------------------------------------------------------------------------------
findFirstChar PROC
PUSH ebp ; save caller base pointer
MOV ebp, esp ; set our base pointer
PUSH edi
PUSH esi ; end prologue
MOV esi, [ebp + 8]
MOV eax, 0
CALL stringLength
POP ecx
mov edi, OFFSET BYTE PTR [esi + eax]
mov al,'eax' ; search for 'eax'
;ecx is already counting length
cld
repne scasb ; repeat while not equal
dec edi ; EDI points to 'eax'
POP esi ; start epilogue
POP edi
MOV esp, ebp ; deallocate locals
POP ebp ; restore caller base pointer
RET
findFirstChar ENDP
END
>>59996763
> cld ; clear destination
cld = clear direction flag
I don't have time right now but if I can find this thread tomorrow I'll write it for you. This can be done in less than 10 lines of asm.
>>59996963
i need it by tomorrow morning though and i know it wont be around...
>>59996747
just write the function in C, compile it with -S, and take a look at the resulting code.
>>59996988
This
>>59996976
Literally all you need is
Lea edi, [string]
Mov eax, [character_arg]
Repne scasb
Cmp byte [edi], eax
Jne .Nf
Sub edi, [string]
Mov eax, edi
Ret
.Nf:
Mov eax, -1
Ret
Just fill in string and character_arg with the address of your arguments.
>>59997018
BTW this is nasm syntax.
>>59997018
Oops actually
Sub edi, [string]
Should be
Sub edi, string
You want to subtract the address
>>59997018
hes making us write a string length though. can i alter this some way to use the string? if this is all i need though i might as well just say fuck it and do this though..
>>59996988
I basically don't know C. Prof that taught everyone C++ didn't teach us at all. basically taught us pseudocode
>>59997164
the only C specific knowledge you need is that strings end with a \0
>>59996747.386P ; use 80386 instruction set
.MODEL flat,C ; use flat memory model
printf PROTO C, :VARARG
.DATA ; declare initialzed data here
target DWORD 100 DUP(?) ;storage space
.STACK ; use default 1k stack space
doPrologue MACRO nvars
PUSH ebp ; save caller base pointer
MOV ebp, esp ; set our base pointer
PUSH edi
PUSH esi ; end prologuee
ENDM
doEpilogue MACRO
POP esi ; start epilogue
POP edi
MOV esp, ebp ; deallocate locals
POP ebp ; restore caller base pointer
ENDM
.CODE ; contains our code
stringLength PROC PUBLIC
doPrologue
MOV esi, [ebp + 8]
MOV eax, 0
cld ; clear destination
mov esi, BYTE PTR [esi + eax] ;start
mov edi, OFFSET target ;emd
INC ecx
rep movsd ;will inc ecx by 1 a as everything is getting coppied
PUSH ecx ;saves the counter number
doEpilogue
RET
stringLength ENDP
;-----------------------------------------------------------------------------------
findFirstChar PROC PUBLIC
doPrologue
;CALL stringLength
POP ecx
mov edi, BYTE PTR [esi + eax]
mov al, [eax] ; search for 'eax'
;ecx is already counting length
cld
repne scasb ; repeat while not equal
jnz negOne ; no value found so, -1
MOV eax, edi ; get the number of which the char is at
doEpilogue;
RET
negONE:
MOV eax,-1
doEpilogue
RET
findFirstChar ENDP
END[code[
>>59997288
here is what i have so far if anyone can just finish this shit so i can copy paste il give you $10 im fucking tired guys and i dont know what to do