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
CodePudding user response:
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
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