如何比较汇编中两个数组的元素?

时间:2022-05-25 12:08:20

I need to solve the following problem:
I need to put 4 arrays in memory, each array has 10 numbers which are the size of one byte.
Now, I need to find the way to check if any of the numbers from one string have a pair in another string and if they do I need to put those answers on to stack.

我需要解决以下问题:我需要在内存中放置4个数组,每个数组有10个数字,这些数字是一个字节的大小。现在,我需要找到检查一个字符串中的任何数字是否在另一个字符串中有一对的方法,如果有,我需要将这些答案放到堆栈上。

This is what I did so far:

这是我到目前为止所做的:

arr1 db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
arr2 db 2, 11, 12, 13, 14, 15, 16, 17, 18, 19
arr3 db 1, 20, 21, 22, 23, 24, 25, 26, 27, 28
arr4 db 1, 29, 30, 31, 32, 33, 34, 35, 36, 37

lea si, arr1
lea di, arr2
mov al, 0
mov bl, 0

mov cx, 10
loopOne:
    loopTwo: 
        cmp [si+al],[di+bl]
        je done
        inc al
        loop loopTwo
    inc bl
    mov al, 0    
loop loopOne 
done: 
mov dl, si+al
inc 21h
ret

I'm using emu8086.

我正在使用emu8086。

EDIT:

This is how it'd look like in Java:

这就是它在Java中的样子:

public class Main {

    public static void main(String[] args) {

        int[] arr1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        int[] arr2 = { 1, 11, 12, 13, 14, 15, 16, 17, 18, 19};
        int[] arr3 = { 1, 20, 21, 22, 23, 24, 25, 26, 27, 28};
        int[] arr4 =  { 1, 29, 30, 31, 32, 33, 34, 35, 36, 37 };
        int a = 0; //counter of matches in every pair of arrays
        for (int i = 0; i < arr1.length ; i++) {
            for( int j = 0; j < arr2.length ; j++){
                if( arr1[i] == arr2[j]){
                    a++;
                }
            }
        }
        //instead of printing, the number of matches ( a ) should be pushed on to stack
        System.out.println("Number of matches: " + a);
        a = 0;
        for (int i = 0; i < arr1.length ; i++) {
            for( int j = 0; j < arr3.length ; j++){
                if( arr1[i] == arr3[j]){
                    a++;
                }
            }
        }
        System.out.println("Number of matches: " + a);
        a = 0;
        for (int i = 0; i < arr1.length ; i++) {
            for( int j = 0; j < arr4.length ; j++){
                if( arr1[i] == arr4[j]){
                    a++;
                }
            }
        }
        System.out.println("Number of matches: " + a);
        a = 0;
        for (int i = 0; i < arr2.length ; i++) {
            for( int j = 0; j < arr3.length ; j++){
                if( arr2[i] == arr3[j]){
                    a++;
                }
            }
        }
        System.out.println("Number of matches: " + a);
        a = 0;
        for (int i = 0; i < arr2.length ; i++) {
            for( int j = 0; j < arr4.length ; j++){
                if( arr2[i] == arr4[j]){
                    a++;
                }
            }
        }
        System.out.println("Number of matches: " + a);
        a = 0;
        for (int i = 0; i < arr3.length ; i++) {
            for( int j = 0; j < arr4.length ; j++){
                if( arr3[i] == arr4[j]){
                    a++;
                }
            }
        }
        System.out.println("Number of matches: " + a);
        a = 0;


    }

}

2 个解决方案

#1


1  

LOOP is designed for small and simple loops. Things become complicated when it is used for longer calculations or for nested loops. I suggest to avoid LOOP in those cases.

LOOP专为小而简单的循环而设计。当用于更长的计算或嵌套循环时,事情变得复杂。我建议在这些情况下避免使用LOOP。

cmp [si+al],[di+bl] is wrong. You cannot compare two values in memory in this way. The so called string operations (scas, movs, cmps) are uncomfortable to handle in a 16-bit environment (MS-DOS) and especially for this task. Furthermore, you cannot add a WORD (si) and a BYTE (bl).

cmp [si + al],[di + bl]错了。您无法以这种方式比较内存中的两个值。所谓的字符串操作(scas,movs,cmps)在16位环境(MS-DOS)中处理起来很不舒服,特别是对于这项任务。此外,您不能添加WORD(si)和BYTE(bl)。

I figured out the first comparison (arr1/arr2) for you and hope you can add the remaining comparisons by yourself.

我想出了你的第一个比较(arr1 / arr2),并希望你能自己添加剩余的比较。

.MODEL small
.STACK

include "emu8086.inc"

.DATA
    arr1 db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    arr2 db 2, 11, 12, 13, 14, 15, 16, 17, 18, 19
    arr3 db 1, 20, 21, 22, 23, 24, 25, 26, 27, 28
    arr4 db 1, 29, 30, 31, 32, 33, 34, 35, 36, 37


.CODE
define_print_num_uns            ; emu8086.inc


start:
    mov ax, @data               ; Initialize DS
    mov ds, ax

    ; Compare arr1 and arr2
    lea si, arr1                ; Reset pointer to arr1
    mov cl, 10                  ; Length of arr1 = loop counter for loopOne
    mov bx, 0                   ; Counter for matches
    loopOne:                    ; Loop through arr1
        mov al, [si]            ; Load one element of arr1
        lea di, arr2            ; Reset pointer to arr2
        mov ch, 10              ; Length of arr2 = loop counter for loopTwo
        loopTwo:                ; Loop through arr2
            mov ah, [di]        ; Load one element of arr2
            cmp al, ah          ; Compare it
            jne @1              ; Skip the next line if no match
            inc bx              ; Increment match counter
            @1:
            inc di              ; Next element in arr2
            dec ch              ; Decrement loop counter
            jne loopTwo         ; Loop - break if CH == 0
        inc si                  ; Next elemnt in arr1
        dec cl                  ; Decrement loop counter
        jne loopOne             ; Loop - break if CL == 0
    mov ax, bx                  ; match counter into AX for print_num_uns
    call print_num_uns          ; emu8086.inc

    mov ax, 4C00h               ; MS-DOS function 4C: Exit program
    int 21h                     ; Call MS-DOS

end start

#2


1  

You are asking too much from x86 assembly.
In any given instruction there can be only one memory operand.

你在x86汇编中问得太多了。在任何给定的指令中,只能有一个内存操作数。

Your cmp [si+al],[di+bl] has two and will thus not assemble.
Also you're using cx as a loop counter for 2 loops. That will not work. After the first loop is finished cx will be 0, aka 65536, meaning the outer loop+inner loop will run 64k times (oops).

你的cmp [si + al],[di + bl]有两个,因此不会组装。你也使用cx作为2个循环的循环计数器。这是行不通的。在第一个循环完成后,cx将为0,即65536,这意味着外循环+内循环将运行64k次(oops)。

Because your intent is unclear I can't really help you with the details of the code.

因为你的意图不清楚,我无法真正帮助你解决代码的细节。

#1


1  

LOOP is designed for small and simple loops. Things become complicated when it is used for longer calculations or for nested loops. I suggest to avoid LOOP in those cases.

LOOP专为小而简单的循环而设计。当用于更长的计算或嵌套循环时,事情变得复杂。我建议在这些情况下避免使用LOOP。

cmp [si+al],[di+bl] is wrong. You cannot compare two values in memory in this way. The so called string operations (scas, movs, cmps) are uncomfortable to handle in a 16-bit environment (MS-DOS) and especially for this task. Furthermore, you cannot add a WORD (si) and a BYTE (bl).

cmp [si + al],[di + bl]错了。您无法以这种方式比较内存中的两个值。所谓的字符串操作(scas,movs,cmps)在16位环境(MS-DOS)中处理起来很不舒服,特别是对于这项任务。此外,您不能添加WORD(si)和BYTE(bl)。

I figured out the first comparison (arr1/arr2) for you and hope you can add the remaining comparisons by yourself.

我想出了你的第一个比较(arr1 / arr2),并希望你能自己添加剩余的比较。

.MODEL small
.STACK

include "emu8086.inc"

.DATA
    arr1 db 1, 2, 3, 4, 5, 6, 7, 8, 9, 10
    arr2 db 2, 11, 12, 13, 14, 15, 16, 17, 18, 19
    arr3 db 1, 20, 21, 22, 23, 24, 25, 26, 27, 28
    arr4 db 1, 29, 30, 31, 32, 33, 34, 35, 36, 37


.CODE
define_print_num_uns            ; emu8086.inc


start:
    mov ax, @data               ; Initialize DS
    mov ds, ax

    ; Compare arr1 and arr2
    lea si, arr1                ; Reset pointer to arr1
    mov cl, 10                  ; Length of arr1 = loop counter for loopOne
    mov bx, 0                   ; Counter for matches
    loopOne:                    ; Loop through arr1
        mov al, [si]            ; Load one element of arr1
        lea di, arr2            ; Reset pointer to arr2
        mov ch, 10              ; Length of arr2 = loop counter for loopTwo
        loopTwo:                ; Loop through arr2
            mov ah, [di]        ; Load one element of arr2
            cmp al, ah          ; Compare it
            jne @1              ; Skip the next line if no match
            inc bx              ; Increment match counter
            @1:
            inc di              ; Next element in arr2
            dec ch              ; Decrement loop counter
            jne loopTwo         ; Loop - break if CH == 0
        inc si                  ; Next elemnt in arr1
        dec cl                  ; Decrement loop counter
        jne loopOne             ; Loop - break if CL == 0
    mov ax, bx                  ; match counter into AX for print_num_uns
    call print_num_uns          ; emu8086.inc

    mov ax, 4C00h               ; MS-DOS function 4C: Exit program
    int 21h                     ; Call MS-DOS

end start

#2


1  

You are asking too much from x86 assembly.
In any given instruction there can be only one memory operand.

你在x86汇编中问得太多了。在任何给定的指令中,只能有一个内存操作数。

Your cmp [si+al],[di+bl] has two and will thus not assemble.
Also you're using cx as a loop counter for 2 loops. That will not work. After the first loop is finished cx will be 0, aka 65536, meaning the outer loop+inner loop will run 64k times (oops).

你的cmp [si + al],[di + bl]有两个,因此不会组装。你也使用cx作为2个循环的循环计数器。这是行不通的。在第一个循环完成后,cx将为0,即65536,这意味着外循环+内循环将运行64k次(oops)。

Because your intent is unclear I can't really help you with the details of the code.

因为你的意图不清楚,我无法真正帮助你解决代码的细节。