简体   繁体   中英

8086 Assembler compare two operands without CMP

question:

In data segment i have two arrays A,B (DW) with size 1 < N < 20 with some numbers (code runs only if arrays length less 20), code need to run in both arrays and check if number in same index of arrays equal, push them in to stack. Note: Need to do that without CMP.

Example A:

A DW 1234,35235,1234,5678
B DW 4532,32735,5678,1234
N=4

The stack will be empty

Example B:

A DW 4532,35235,1234,5678 
B DW 4532,32735,1234,1234
N=4

Numbers 4532 and 1234 goes to stack

My code:

DATA SEGMENT
    A DW 4535
    B DW 4535
    SIZEA = OFFSET B /2
    SIZEB = ($-B)/2
DATA ENDS  

CODE SEGMENT
    ASSUME CS:CODE, DS:DATA
    START:   
    MOV AX,DATA
    MOV DS,AX   
    MOV SP,100h      
    MOV CX,SIZEB ;how times loop run
    MOV DX,SIZEA ;to compare sizes of arrays
    TEST CX,19   ;if size of array B above 19 numbers jump to end
    JNP END
    TEST DX,19   ;if size of array A above 19 numbers jump to end
    JNP END
    XOR DX,CX    ;if arrays size not equal jump to end
    JNZ END


    MOV SI,0    ;index of array
CHECK: 
    MOV AX,A(SI)
    MOV BX, B(SI)
    SUB AX,BX  ;if same numbers zf=1, jump to find
    JZ FIND
    ADD SI,2   ;goes to next index (2 because DW)
    LOOP CHECK ;checking next index
    JMP END    ;when cx = 1 jump to end
FIND: 
    PUSH BX    ;pushing to stack equal number
    ADD SI,2
    LOOP CHECK 
END:
CODE ENDS 
END START 

This works except for length 19,16,14,13,10,9,6,5,2,1

TEST CX,19   ;if size of array B above 19 numbers jump to end
JNP END
TEST DX,19   ;if size of array A above 19 numbers jump to end
JNP END
XOR DX,CX    ;if arrays size not equal jump to end
JNZ END

Why don't you use TEST and SUB to test these conditions? The original questions states 1 < N < 20 . The example program already violates this condition. It uses N=1.

sub dx,cx
jnz end     ;exit different sized arrays
test cx,cx
jle end     ;exit [-32768,0]
dec cx
jz end      ;exit 1
sub cx,19
jns end     ;exit [20,32767]
mov cx,SIZEB
DATA SEGMENT
    A DW 4535
    B DW 4535
    B_A = OFFSET B - OFFSET A
    SIZEA = B_A /2
    SIZEB = ($-B)/2
DATA ENDS

CODE SEGMENT
    ASSUME CS:CODE, DS:DATA
START:
    MOV AX,DATA
    MOV DS,AX
    MOV SP,100h
    MOV CX,SIZEB    ;how times loop run
#IFDEF DontUseAssDir
    MOV DX,SIZEA    ;to compare sizes of arrays
    XOR DX,CX       ;if arrays size not equal jump to end
    JNZ END
    MOV AX,19
    SUB AX,CX       ;if size of array B above 19 numbers jump to end
    JC END
    SUB AX,18       ;if size of array B below 2 numbers jump to end
    JC END
#ELSEIF NOT SIZEA = SIZEB
# ERR A and B have different sizes
#ELSEIF 19 < SIZEA
# ERR A and B are larger than 19 elements
#ELSEIF SIZEA < 2
# ERR A and B are smaller than 2 elements
#ENDIF

    MOV SI,OFFSET A ;address of array
    CLD
#IF CPU=8086 OR CPU=80186
    ALIGN 2        ;align address for loop if 8086, don't bother for 8088
#ENDIF
CHECK:
    MOV BX, B_A(SI) ;get B(SI)
    LODSW           ;get A(SI) and ADD SI,2
    SUB AX,BX       ;if same numbers zf=1, don't loop
    LOOPNE CHECK    ;checking next index unless equal

    JNE END         ;job done, if not equal
    PUSH BX         ;pushing to stack equal number
    JCXZ END        ;don't loop if cx=0
    JMP CHECK       ;else next index
END:
    CODE ENDS
END START

If bounds are fixed, use the assembler to check them. No need to check bounds for both A and B, if they are supposed to be of same size. Since SI isn't checked, better place address in SI and use difference between A and B addressses for other MOV.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM