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
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:
...
Using separate loops for the rising and falling edges of the sawtooth. Not only are the new loops very short, they can iterate over just one conditional branch thanks to sticking a sentinel to the end of the array. The sentinel is chosen such that the loop has got to end. The position where the loop exit occurs then decides about success or failure:
mov si, offset ARR ; Address of the array
mov cx, ... ; Number of array elements
call TestWavy ; -> AL=[0,1]
mov [REZ], al
...
; IN (cx,si) OUT (al) MOD (ah,bx,cx,dx,si,di)
TestWavy:
cld ; Clear DF so LODSW will SI++
mov bx, cx
shr bx, 1
jz .fine ; In case of 0 or 1 array elements
lea di, [si+bx]
add di, bx
mov dx, [di] ; Preserve existing bytes
mov word ptr [di], 0102h ; Sentinel for the rising edge
push si ; (1)
.rise:
lodsw
cmp al, ah
jng .rise
mov [di], dx ; Restore the bytes
cmp si, di
pop si ; (1)
jbe .wrong
inc si ; Address of the first falling edge
dec cx
shr cx, 1
jz .fine ; In case of 2 array elements
mov di, si
add di, cx
add di, cx
mov dx, [di] ; Preserve existing bytes
mov word ptr [di], 0201h ; Sentinel for the falling edge
.fall:
lodsw
cmp al, ah
jnl .fall
mov [di], dx ; Restore the bytes
cmp si, di
jbe .wrong
.fine:
mov al, 1
ret
.wrong:
mov al, 0
ret
Using the byte-sized registers to the fullest. This minimizes the number of memory accesses as well as the number of iterations on the loop. Every iteration is guaranteed to be able to perform 8 comparisons, thanks to replicating the last element 7 times. The idea is, that this way, no early exits have to be included. And don't forget that you need to keep 7 unoccupied bytes after the array.
mov si, offset ARR ; Address of the array
mov cx, ... ; Number of array elements
call TestWavy ; -> AL=[0,1]
mov [REZ], al
...
; IN (cx,si) OUT (al) MOD (ah,bx,cx,dx,si,di,bp)
TestWavy:
sub cx, 1
jbe .fine ; In case of 0 or 1 array elements
cld ; Clear DF so LODSW will SI++
mov bp, cx ; and STOSB will DI++
lea di, [si+bp] ; Address of the last element
mov al, [di]
mov cx, 8
rep stosb
.more:
lodsw ; Load 8 elements
xchg dx, ax ; `mov dx, ax`
lodsw
xchg cx, ax ; `mov cx, ax`
lodsw
xchg bx, ax ; `mov bx, ax`
lodsw
cmp dl, dh ; Check 4 rising edges
jg .wrong
cmp cl, ch
jg .wrong
cmp bl, bh
jg .wrong
cmp al, ah
jg .wrong
cmp dh, cl ; Check 4 falling edges
jl .wrong
cmp ch, bl
jl .wrong
cmp bh, al
jl .wrong
cmp ah, [si]
jl .wrong
sub bp, 8
ja .more
.fine:
mov al, 1
ret
.wrong:
mov al, 0
ret