0

I have to find the (beginning) positions of a substring in a string. I load the string byte by byte in AL and compare it using SCASB. How can I check if the bytes are equal or if SCASB is true?

        clc
        scasb ;compare the value from al with <es:di>
              ;al is loaded from <ds:si>(lodsb)
              ;I noticed that when the values are equal
              ;cf and af are 1
        jnc nextElem ;if cf is 0 go to the next element

        lahf
        cmp  ah,0
        je nextElem ;if af is 0 go to next elem

The problem is that LAHF doesn't bring the value that I expected in ah, meaning is not 0 or 1, and I don't know any other way to check if the values in AL and are equal.

zx485
  • 28,498
  • 28
  • 50
  • 59
shanto
  • 11
  • 4
  • 1
    Mention some more details. – Tirthraj Barot Nov 19 '16 at 10:37
  • 2
    First sentence of documentation for the `scasb` instruction: "SCASB compares the byte in AL with the byte at [ES:DI] or [ES:EDI], and sets the flags accordingly." If you want to check for equality, then use ZF. CF is for testing if less than. – Raymond Chen Nov 19 '16 at 11:48
  • @TirthrajBarot I added some code in the question. I hope you understand what I mean. – shanto Nov 19 '16 at 11:49
  • @RaymondChen I tried but the zf doesn't change so it just goes on even if the values are different.. – shanto Nov 19 '16 at 11:56
  • 1
    Why are you using LAHF in the first place? Why not just branch on a condition since you already have the flags you want in EFLAGS. – Peter Cordes Nov 19 '16 at 12:30

3 Answers3

1

I changed the code a bit and this is it:

mov  cx,length  ; length of the substring
repe cmpsb      ; compare <ds:si> with <es:di> 
jcxz Pozitie    ; if cx is zero than we found the substring in the string
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
shanto
  • 11
  • 4
  • REPE CMPSB also leaves flags set, and JCC on flags is usually more efficient than JCXZ (e.g. [2 uops instead of 1 on Intel SnB-family. Nowhere near as bad as LOOP, though](http://stackoverflow.com/q/35742570/224132). I haven't tested this, but `JNE Pozitie` should be an exact replacement for JCXZ here, true only if `repe cmpsb` stopped early. – Peter Cordes Nov 27 '16 at 03:03
1

If you want not using jump instruction and you use "RepNE ScaSB" string instruction, to find the offset of the previous don't matching character (CX), you may write:

 ClD             {Clear string direction flag}

 XOr   AL,AL     {Set AL's reg. with the character to find (0)}
 Mov   CX,0FFFFH {Set CX's reg. with maximum length of the string}

 RepNE ScaSB     {Search null and decrease CX's reg.}

 LAHF            {Load FZero flag into AH (Bit6)}
 Not   CX        {Set CX with the number of char scanned}
 ShL   AH,1      {...}
 ShL   AH,1      {... FCarry is set with (FZero after scan)}
 SbB   CX,0      {If it founds 0 decrease CX's reg.}

If CX=65535 you haven't found the character.

Hi!

Paolo Fassin
  • 361
  • 2
  • 11
  • `shl ah, 2` would be more efficient (except on Intel P6-family, where using the flag-result of an imm8 shift will stall). This isn't an 8086-only question (although it does seem to be 16-bit). Also, can you stop putting "Hi!" at the bottom of your answers? Stack Overflow doesn't allow signature lines. – Peter Cordes Oct 11 '17 at 21:24
  • Can you `setz al` or `setnz al` / `sub ax, cx` or something? (If you zeroed the whole AX/EAX before scasb, instead of just AL). There's probably another + or - 1 or something needed there to account for NEG vs. NOT 2's complement. – Peter Cordes Oct 11 '17 at 21:28
0

Scasb, cmpsb are useful only when used on strings, with length/counter in CX register. Here is strstr implemented in 8086 asm:

http://techref.massmind.org/techref/language/asm/x86/stdlib/STRSTR.ASM

The idea is to use scasb with repne prefix (repeat while not equal) to find first char of substring in string. if found, rest of the string is compared using repe cmpsb.

Flanker
  • 408
  • 3
  • 7
  • You would better show an actual example rather than providing this link! – Sep Roland Nov 20 '16 at 16:52
  • well the author(s) explicitly asked "PLEASE DON'T RIP! DO: LINK", it is on the top of the page :) – Flanker Nov 20 '16 at 16:54
  • 1
    I don't agree that `scasb`, ... are only useful when used on strings with length in `CX` register. `scasb` and friends came perfectly operate without using the `CX` register. – Sep Roland Nov 20 '16 at 16:54
  • 1
    Even so. If the author doesn't permit copying, then invent an example of your own. – Sep Roland Nov 20 '16 at 16:56