2015-02-04 4 views
1

вопрос:8086 Ассемблер сравнивает два операнда без CMP

В сегменте данных у меня есть два массива A, B (DW) с размером 1 < N < 20 с некоторыми чисел (код работает только тогда, когда длина массива меньше 20), код необходимо запустить в обоих массивах и проверить, равно ли число в одном индексе массивов, вталкивать их в стек. Примечание: нужно сделать это без CMP.

Пример:

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

+0

Интересно, почему вы не можете использовать CMP. В любом случае, почему бы не просто вычесть одну форму другой и проверить на нуль? (вам, возможно, придется немного настроить отрицательные числа) – Mawg

+0

Это пример экзамена в Assembler, я должен сделать это на следующей неделе. В вопросе написано: Напишите код без использования CMP =) –

+0

Способ использования 'TEST' не соответствует вашему комментарию ', если размер выше 19'. –

ответ

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, чтобы проверить эти условия ? Исходные вопросы: N . Пример программы уже нарушает это условие. Он использует 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 
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 и использовать разницу между адресами A и B для других MOV.

Смежные вопросы