arraysassemblyx86-16tasm

how to check if an arr is "wavy"?


my code should check if an ARR is "'wavy" which means the first element is less then the second, the second is greater then the third and same as this till the end of the arr.. but it doesn't work.. here is the code:

IDEAL
MODEL small
STACK 100h
DATASEG

        
ARR db 3 dup (?)
REZ db 1


CODESEG
start:
    mov ax,@data
    mov ds,ax
    mov cx,3                    ;cx=99
    xor ax,ax                    ; ax=0
    xor si,si                    ;si=0
    
    mov [ARR],0
    mov [ARR+1], 1
    mov [ARR+2], 0
    lea bx,[ARR]                 ; bx=offset arr
    L1: cmp cx,1
        je finish
        mov di,cx                ;di=cx (as index)
        neg di                   ;di=-di
        lea si,[bx+di] 
        mov ax,[3+si]
        cmp ax,[4+si]      ; compre the odd vs even index                                                   illegal use of register
        jg wrong                             ; exit if the odd index > even index
        dec cx                               ; cx=cx-1
        cmp cx,0                             ; check if cx=0
        je finish                            ; if  cx=0 finish
        mov di,cx                ;di=cx (as index)
        neg di                   ;di=-di
        lea si,[bx+di] 
        mov ax,[3+si]
        cmp ax,[4+si]        ; compre the even vs odd index                                                 illegal use of register
        jl wrong                            ; exit if the even <odd index
        loop L1                             ; cx=cx-1      if cx!=0 -> jump to L1
    wrong:
        mov [REZ],0
    finish:
    


exit:
    mov ax,4c00h
    int 21h
END start


there is even an example but it doesn't work..
do u know where is the mistake?

in the end we should end with res=1 if the arr is "wavy" or if it is not wavy arr=0


Solution

  • You have a mismatch between the size of the array elements (byte), and the size of the operations that you perform on these elements (word).

    The definition ARR db 3 dup (?) does not match the code mov ax,[3+si] cmp ax,[4+si]. You need to write mov AL, [3+si] cmp AL, [4+si] instead.

    When the loop ends, you should not fall-through into wrong, but rather jmp to exit.

    A single address register is enough:

      sub  cx, 1
      jbe  exit         ; In case of 0 or 1 array elements
      lea  si, [ARR]
      cld               ; Clear direction flag so LODSB will increment SI
    L1:
      lodsb
      cmp  al, [si]
      jg   wrong
      dec  cx
      jz   exit
      lodsb
      cmp  al, [si]
      jl   wrong
      loop L1
      jmp  exit
    wrong:
      ...
    exit:
      ...
    

    It is fascinating to explore alternative solutions