2017-06-03 3 views
0

Ich muss das folgende Problem lösen:
Ich muss 4 Arrays im Speicher, jedes Array hat 10 Zahlen, die die Größe von einem Byte sind.
Jetzt muss ich den Weg finden zu überprüfen, ob eine der Zahlen aus einer Zeichenfolge ein Paar in einer anderen Zeichenfolge haben, und wenn sie es tun, muss ich diese Antworten auf Stack setzen.Wie Elemente von zwei Arrays in Assembly zu vergleichen?

Das ist, was ich bisher getan:

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 

Ich emu8086 verwenden.

EDIT:

Dies ist, wie es in Java aussehen würde:

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; 


    } 

} 
+0

Können Sie einen Java-Code hinzufügen, der zeigt, was Sie versuchen zu tun. Es ist mir immer noch nicht klar. – Johan

Antwort

1

LOOP ist für kleine und einfache Schleifen ausgelegt. Die Dinge werden kompliziert, wenn sie für längere Berechnungen oder für verschachtelte Schleifen verwendet werden. Ich schlage vor, in diesen Fällen LOOP zu vermeiden.

cmp [si+al],[di+bl] ist falsch. Auf diese Weise können Sie zwei Werte im Speicher nicht vergleichen. Die sogenannten String-Operationen (scas, movs, cmps) sind in einer 16-Bit-Umgebung (MS-DOS) und speziell für diese Aufgabe unbequem zu handhaben. Außerdem können Sie kein WORD (si) und kein BYTE (bl) hinzufügen.

Ich fand den ersten Vergleich (arr1/arr2) für Sie und hoffe, dass Sie die verbleibenden Vergleiche selbst hinzufügen können.

.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 
+0

Vielen Dank, ich beendete den Rest. Ich schätze die ausführlichen Kommentare. Es ist mir nur unklar, was genau '@data' tut? – Pantokrator

+0

@Pantokrator: Die meisten Befehle, die im Speicher arbeiten (z. B. "mov al, [si]"), verwenden implizit das Segmentregister "DS" zur Adressierung. Beim Programmstart hat 'DS' nicht den richtigen Wert. '@ data' ist eine Kurzform für' Segment des .DATA-Abschnitts'. 'mov ds, ax' lädt diese Adresse nach' DS'. Dies wird als "Initialisierung von DS" bezeichnet. – rkhb

+1

Sicherlich eine gute Antwort (+1), aber ich verstehe nicht, warum die String-Operationen in einer MS-DOS-Umgebung __unkomfortabel sind. Ich hatte nie Probleme, sie unter DOS zu benutzen. – Fifoernik

1

Sie sind zu viel von x86-Assembler zu fragen.
In jeder gegebenen Anweisung kann nur ein Speicheroperand vorhanden sein.

Ihre cmp [si+al],[di+bl] hat zwei und wird somit nicht zusammenbauen.
Auch Sie verwenden cx als einen Schleifenzähler für 2 Schleifen. Das wird nicht funktionieren. Nachdem die erste Schleife beendet ist, wird cx 0, alias 65536, sein, was bedeutet, dass die äußere Schleife + innere Schleife 64k mal (oops) läuft.

Da Ihre Absicht unklar ist, kann ich Ihnen nicht wirklich mit den Details des Codes helfen.

+0

Vielen Dank für eine schnelle Antwort, ich muss das folgende Problem lösen: Ich muss 4 Arrays in den Speicher, jedes Array hat 10 Zahlen, die die Größe von einem Byte sind. Ich muss nur diese Zahlen in den Speicher legen, es gibt keine Notwendigkeit für die Eingabe von Daten über die Tastatur. Jetzt muss ich den Weg finden, um zu überprüfen, ob eine der Zahlen aus einer Zeichenfolge ein Paar in einer anderen Zeichenfolge hat, und wenn dies der Fall ist, muss ich diese Antworten auf den Stack setzen. Ich programmiere in Java und wann immer ich zwei Arrays vergleichen musste, musste ich zwei Schleifen verwenden. Ich bin es gewohnt, anders zu denken und zu codieren. – Pantokrator

+2

Es ist nicht so, dass Sie nicht zwei Schleifen verwenden sollten, der Punkt ist, dass Sie nicht das gleiche Register für beide verwenden können - oder wenn Sie dies tun, müssen Sie es speichern/wiederherstellen. Es gibt kein lexikalisches Scoping in der Assembly. Wenn Sie ein Register in einer inneren Schleife überschreiben, behält es diesen Wert auch in der äußeren Schleife bei. –