/* This program expected to perform the following tasks:
	
	1. Prompt and read a source string from the user into the
	memory location(s) pointed by source symbol.
	
	2. Prompt and read the string to be deleted from the user into
	the memory location(s) pointed by delStr symbol.

	3. Remove each occurance of the delStr string from the source
	string.

	4. Print the source string.
*/	
.text
	
.globl _start

_start:
	/* First read the two string inputs from the user after
	   displaying the necessary prompt messages. Begin with reading
	   the source string. Set the prompt string to be displayed.

	   int srcOrDel = 2;
	   char dest[]  = source;
	   String ecx   = prompt1;
	   int    edx   = ecx.length();
	   do {
	      int eax = 4;
	      int ebx = 1;
	      int0x80(eax, ebx, ecx, edx); // System.out.println(ecx)

              // Read characters into dest array
	      if (srcOrDel > 0) {
	          ecx = prompt2	;
	          edx = prompt2.length() ;
	          dest= delStr;
	      }
	   } while (srcOrDel > 0) ;
	*/
	movl $prompt1,   %ecx /* Put the address of prompt in ecx */
	movl $prompt1Len,%edx /* Place number of characters to display */
        movl $source,    dest /* Place target of input chars           */
	
getNextInput:
	/* Assume ecx and edx are setup and display prompt */
	movl $4, %eax  /* The system call for write (sys_write) */
	movl $1, %ebx  /* File descriptor 1 - standard output */
        int $0x80           /* Call to the Linux OS */

	/* The next set of instructions implement the following
	   while loop 

           char c;
           while ((c = getchar()) != '\n') {
               (dest) = c;
	       dest++;
           }
	   (dest) = '\0';
        */
readNextChar:	
        movl $3, %eax    /* The system call for read (sys_read) */
        movl $0, %ebx    /* File descriptor 0 - standard input */
        movl $c, %ecx    /* Put the address of buffer in ecx */
        movl $1, %edx    /* Place number of characters to read in edx */
        int $0x80        /* Call to the Linux OS */

        cmpb $'\n', c    /* Is the character '\n'? */
        jne  storeChar
	movb $0, c       /* if so change it to '\0' to end string */
storeChar:
	movb c, %bl
	movl dest, %eax    /* Store destination address in eax */
	movb %bl, (%eax)   /* Store character into string */
	incl dest          /* dest++ */
	cmpb $0, c         /* Has end of string been stored? */
	jne  readNextChar

	/* OK, an input string has been successfully read. */
	/* Do we have another input to obtain?             */
	decl srcOrDel
	jz   doStringProcessing /* Done reading 2 inputs */

	/* OK. So one input has been read. Setup and read the *
	/* delete string from the user */
	movl $prompt2, %ecx
	movl $prompt2Len, %edx
	movl $delStr, dest
	jmp  getNextInput
	
doStringProcessing:
	movl $source, %eax    /* source index for search start */

search:	
	movl %eax, %esi       /* Let esi point to search start */
	movl $delStr, %edi    /* Let edi point to characters in delStr */

checkMatch:	
        cmpb $0, (%edi)    /* If we reach end-of-string in delStr */
	je   deleteStr        /* then we got a match */
	
	cmpb $0, (%esi)    /* if we have reached end of string  */
	je   showResult       /* in source we cannot have a match  */

	movb (%edi), %bl
	cmpb %bl, (%esi)      /* Is search[esi] == delStr[edi]?    */
	jne  nextSourceChar   /* No match! onto next source char   */
	
	incl %esi             /* Found a char match. Check if next */
	incl %edi             /* Character also matches.           */
	jmp  checkMatch

deleteStr:
	/* When control drops here, that means we found a match */
	/* eax points to initial location while esi points to   */
	/* the address from where data is to be copied.         */

	/* int ecx = eax;
	   while (source[esi] != '\0') {
	        source[ecx] = source[esi];
	        ecx++;
	        esi++;
	   }
	*/
	movl %eax, %ecx 
copyChar:
	movb (%esi), %bl
	movb %bl, (%ecx)
	cmpb $0,  (%esi)
	je   search
	incl %esi
	incl %ecx
	jmp  copyChar
	
nextSourceChar:
	incl %eax             /* Move to next character in source */
	jmp  search           /* Search and delete... */

showResult:
	/* Now eax points to the last character in the string */
	/* Use it as a handy tool to detect end of string     */
	subl $source, %eax
	movl %eax, finalLen

	/* Now display the message */
	movl $4, %eax         /* The system call for write (sys_write) */
	movl $1, %ebx         /* File descriptor 1 - standard output   */
	movl $prompt3, %ecx   /* Address of string to display          */
	movl $prompt3Len, %edx/* Set edx to number of chars to display */
	int  $0x80

	/* Now display the result string */
	movl $4, %eax      /* The system call for write (sys_write) */
	movl $1, %ebx      /* File descriptor 1 - standard output   */
	movl $source, %ecx /* Address of string to display          */
	movl finalLen, %edx/* Set edx to number of chars to display */
	int  $0x80

	/* Now display the final newline character */
	movl $4, %eax         /* The system call for write (sys_write) */
	movl $1, %ebx         /* File descriptor 1 - standard output   */
	movl $prompt4, %ecx   /* Address of string to display          */
	movl $prompt4Len,%edx /* Set edx to number of chars to display */
	int  $0x80

exit:
	mov $1, %eax          /* The system call for exit (sys_exit) */
        mov $1, %ebx          /* Exit with return code of 0 (no error) */
        int $0x80
	
.data

source:	.space 1024
delStr:	.space 1024

/* Variables introduced to ease program development */
srcOrDel: .int 2   /* Variable to indicate if source or delStr */
	           /* is being read to minimize code. */

c:	.byte   0  /* Character read from the user */
	
dest:	.int 0     /* Address of destination buffer */

startIdx: .int 0   /* Starting index for search */
srchIdx:  .int 0   /* Searching index */
delIdx:	  .int 0   /* Index within the delete string */
finalLen: .int 0   /* Length of the resulting string */

/* Static messages for display purposes */
prompt1: .ascii "Enter source string   : "
.equ prompt1Len, . - prompt1

prompt2: .ascii "Enter string to delete: "
.equ prompt2Len, . - prompt2

prompt3: .ascii "The resulting string is: '"
.equ prompt3Len, . - prompt3

prompt4: .ascii "'\n"
.equ prompt4Len, . - prompt4

