So my current attempt at learning MASM isn't going well. Maybe I need to pick a new language. ><
Here's the deal: I have to get two strings from the user, one string and one "search" as it were, something to search for in the main string they entered the first time. Then once it's been found, I have to remove the rest of the string and display only that. I've so far been able to remove things from strings but I can't figure out how to do it from a search. The problem is I don't know how to tell the program where to start removing as scasb gives me the pointer to the letter in EDI but I can't use that as a number of positions from the beginning to start. So I'm rather confused . . . this is what I have so far . . . it's probably a mess . . . and terribly wrong . . .
TITLE ch09_03 (ch09_03.asm)
INCLUDE Irvine32.inc
Str_remove PROTO,
pStart:PTR BYTE,
nChars:DWORD
.data
targetS BYTE 100 DUP (?),0
sourceS BYTE 100 DUP (?),0
pos DWORD ?
str1len DWORD ?
str2len DWORD ?
startpoint DWORD ?
counter DWORD 0
prompt1 BYTE "Please enter a string: ",0
prompt2 BYTE "Please enter a search: ",0
result BYTE "Found: ",0
.code
main PROC
call Clrscr
mov edx, OFFSET prompt1
call writestring
mov ecx,(SIZEOF targetS)
mov edx,OFFSET targetS
call readstring
INVOKE Str_length,
ADDR targetS
mov str1len,eax
mov edx,OFFSET prompt2
call writestring
mov ecx,(SIZEOF targetS)
mov edx,OFFSET sourceS
call readstring
INVOKE Str_length,
ADDR sourceS
mov str2len,eax
mov esi,0
L1:
mov edi,OFFSET targetS
mov al,sourceS[esi]
mov ecx,LENGTHOF targetS
cld
repne scasb
jnz L2
dec edi
.IF (esi == 0)
mov startpoint,edi
.ENDIF
inc counter
inc esi
jmp L1
L2:
.IF (counter == 0)
jmp quit
.ENDIF
INVOKE Str_remove,
edi,
counter
mov edx,OFFSET result
call writestring
mov edx, edi
call writestring
quit:
call crlf
main ENDP
exit
;------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------
Str_remove PROC,
pStart:PTR BYTE, ; points to first character to delete
nChars:DWORD ; number of characters to delete
;
; Removes a block of characters from a string. The
; algorithm involves skipping over the positions that
; will be deleted, and copying the remaining characters
; backward. Each copied character overwrites one of the
; deleted positions. If nChars is too large, all remaining
; characters in the string will be removed.
;-------------------------------------------------------
INVOKE Str_length, ; get string length
pStart ; points to start of string
mov ecx,eax ; ECX = length of string
.IF nChars <= ecx ; check range of nChars
sub ecx,nChars ; set counter for REP prefix
.ENDIF
mov eax,pStart
mov esi,eax ; points to string
add esi,nChars ; points to first character to copy
mov edi,eax ; points to destination position
cld ; clear direction flag (forward)
rep movsb ; do the move
mov BYTE PTR [edi],0 ; insert new null byte
Exit_proc:
ret
Str_remove ENDP
;------------------------------------------------------------------------------------------------------------
;------------------------------------------------------------------------------------------------------------
END main
Okay, here is my idea, Either display the search string directly :bdg . Or do the following.
1. Copy the code from (SCASB pointer-length_of_search) to Scasb pointer to start of string. Put a NULL at the end. Display the string.
So after repne scasb do:
sub edi,strlen2
mov esi,edi
mov edi,OFFSET targetS
mov ecx,strlen2
rep movsb
mov byte ptr[edi+ecx],0
; Do whatever you want to display targetS.
Thomas :U
I tried inserting that code, though I was a little confused as to what it would do, but it's still not working. Do I need to comment out any of this?
jnz L2
dec edi
.IF (esi == 0)
mov startpoint,edi
.ENDIF
inc counter
inc esi
jmp L1
L2:
.IF (counter == 0)
jmp quit
.ENDIF
And then what about my Str_remove procedure? What would I send to it? It's what I'm supposed to develop in this particular program, so I can't really just leave it out or anything . . . man I really need to get better at this stuff...