8086 汇编器比较两个没有 CMP 的操作数

8086 Assembler compare two operands without CMP

问题:

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.

示例 A:

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

堆栈将为空

示例 B:

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

数字 4532 和 1234 入栈

我的代码:

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 

这适用于长度 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

为什么不使用 TEST 和 SUB 来测试这些条件?原始问题表明 1 < N < 20。示例程序已经违反了这个条件。它使用 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

如果边界是固定的,请使用汇编器检查它们。 如果 A 和 B 的大小应该相同,则无需检查它们的边界。 由于未检查 SI,最好将地址放在 SI 中,并将 A 和 B 地址之间的差异用于其他 MOV。