2017-06-03 144 views
0

我需要解決以下問題:
我需要把4個數組放在內存中,每個數組有10個數字,它們是一個字節的大小。
現在,我需要找到方法來檢查一個字符串中的任何數字是否在另一個字符串中有一對,如果他們確實需要將這些答案放在堆棧中。如何比較兩個數組中的元素?

這是我做過什麼,到目前爲止:

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 

我使用emu8086。

編輯:

這是怎麼會看起來像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; 


    } 

} 
+0

你可以添加一些java代碼來展示你正在嘗試做什麼。這仍然不清楚。 – Johan

回答

1

LOOP適用於小而簡單的環路。當它用於更長的計算或嵌套循環時,情況變得複雜。我建議在這些情況下避免LOOP

cmp [si+al],[di+bl]是錯誤的。您無法以這種方式比較內存中的兩個值。所謂的字符串操作(scas,movs,cmps)在16位環境(MS-DOS)中處理很不舒服,尤其是對於此任務。此外,您不能添加WORD(si)和BYTE(bl)。

我想出了第一個比較結果(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 
+0

非常感謝,我完成了其餘的工作。我很欣賞詳細的評論。 我只是不清楚'@data'究竟做了什麼? – Pantokrator

+0

@Pantokrator:對內存進行操作的最大指令(例如'mov al,[si]')隱含地使用段寄存器「DS」進行尋址。在程序開始時,「DS」的值不正確。 '@ data'是'.DATA部分'段的簡寫形式。 'mov ds,ax'將該地址加載到'DS'。這被稱爲「初始化DS」。 – rkhb

+1

當然是一個很好的答案(+1),但我不明白爲什麼字符串操作會在MS-DOS環境下處理__uncomfortable__。在任何DOS環境下,我從來沒有遇到任何麻煩。 – Fifoernik

1

你問從x86彙編太多。
在任何給定的指令中,只能有一個內存操作數。你的cmp [si+al],[di+bl]有兩個,因此不會組裝。
此外,您使用cx作爲2個循環的循環計數器。這是行不通的。第一個循環完成後cx將爲0,也稱爲65536,這意味着外部循環+內部循環將運行64k次(oops)。

因爲您的意圖不清楚,我不能真正幫助您瞭解代碼的細節。

+0

感謝您的快速回復,我需要解決以下問題: 我需要將4個數組放在內存中,每個數組都有10個數字,它們是一個字節的大小。我只需要把這些數字放在內存中,我不需要從鍵盤輸入數據。 現在,我需要找到方法來檢查一個字符串中的任何數字是否在另一個字符串中有一對,如果他們確實需要將這些答案放在堆棧中。 我用Java編程,每當必須比較兩個數組時,我必須使用兩個循環。我習慣於不同的思維和編碼方式。 – Pantokrator

+2

這不像你不應該使用兩個循環,問題是你不能使用同一個寄存器 - 或者,如果你這樣做,你必須保存/恢復它。在彙編中沒有詞彙作用域這樣的事情,如果在內部循環中覆蓋寄存器,它將保持該值,即使在外部循環中也是如此。 –