8086汇编程序在没有CMP的情况下比较两个操作数

时间:2015-02-04 13:13:21

标签: assembly x86-16

问题:

  

在数据段中我有两个数组A,B(DW),大小为1 < N < 20   数字(代码仅在数组长度小于20时运行),代码需要运行   在两个数组中并检查数组的相同索引中的数字是否相等,   将它们推入堆叠。注意:没有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

Numbers 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

之外,这是有效的

2 个答案:

答案 0 :(得分: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&lt; N&lt; 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

答案 1 :(得分:0)

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中放置地址,并使用其他MOV的A和B地址之间的差异。