Returning pointer to the letter in string

2019-06-04 02:23发布

问题:

This is my code to search ih some string consists of one letter:

selectedWords BYTE "BICYCLE"
inputLetter BYTE 'Y'

cld                                 
mov ecx, LENGTHOF selectedWords     
mov edi, offset selectedWords       
mov al, inputLetter                 ;Load character to find
repne scasb                         ;Search
jne notfound

But how to return the pointer to the letter in string?

If I want after to change one leter with some other. Its easy to do if you have pointer to the letter in string.

回答1:

If repne scasb finds the element, EDI points to the element after the first match. You have to decrement it to get the pointer to the desired element.

You don't need to clear the direction flag (cld). It's very very unlikelikely that the direction flag is set without any involvement of your part. And if so, you should seit it back to the former status.

INCLUDE Irvine32.inc

.DATA
selectedWords BYTE "BICYCLE"
inputLetter BYTE 'Y'

err_msg BYTE "Not found.", 0

.CODE
main PROC

    mov ecx, LENGTHOF selectedWords
    mov edi, offset selectedWords
    mov al, inputLetter                 ; Load character to find
    repne scasb                         ; Search
    jne notfound

    dec edi
    mov al, [edi]
    call WriteChar                      ; Irvine32: Write a character in AL

    exit                                ; Irvine32: ExitProcess

    notfound:
    lea edx, err_msg
    call WriteString                    ; Irvine32: Write a null-terminated string pointed to by EDX
    exit                                ; Irvine32: ExitProcess

main ENDP

END main

If you don't like repne scasb you can scan the word with a "normal" comparison loop

INCLUDE Irvine32.inc

.DATA
selectedWords BYTE "BICYCLE"
inputLetter BYTE 'Y'

err_msg BYTE "Not found.", 0

.CODE
main PROC

    mov edi, offset selectedWords
    mov ecx, LENGTHOF selectedWords
    mov al, inputLetter

    @@:
    cmp [edi], al                       ; Compare memory/immediate value
    je found                            ; JE = jump if equal
    inc edi                             ; Increment pointer
    dec ecx                             ; Decrement counter
    jne @B                              ; Jump back to the last @@, if ECX == 0

    jmp notfound

    found:
    mov al, [edi]
    call WriteChar                      ; Irvine32: Write a character in AL

    exit                                ; Irvine32: ExitProcess

    notfound:
    lea edx, err_msg
    call WriteString                    ; Irvine32: Write a null-terminated string pointed to by EDX
    exit                                ; Irvine32: ExitProcess

main ENDP

END main


回答2:

If you read the documentation for REP and SCASB you'll see that SCAS updates edi. Thus the location of the matching char is stored in EDI.
All you have to do is return EDI if ZF=1 and return 0 if ZF<>1.

  cld                                 
  mov ecx, LENGTHOF selectedWords     
  mov edi, offset selectedWords       
  mov al, inputLetter                 ;Load character to find
  repne scasb                         ;Search
  jne notfound
found:
  mov eax,edi                   ;return the address of the match.
  ret
notfound:
  xor eax,eax                   ;return 0 aka not found as address.
  ret