如何在汇编中比较两个数组的元素?
How to compare elements of two arrays in assembly?
我需要解决以下问题:
我需要在内存中放入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;
}
}
你对 x86 程序集的要求太高了。
在任何给定的指令中,只能有一个内存操作数。
您的 cmp [si+al],[di+bl]
有两个,因此不会 assemble。
您还使用 cx
作为 2 个循环的循环计数器。这是行不通的。第一个循环完成后 cx
将为 0,即 65536,这意味着外循环 + 内循环将 运行 64k 次(oops)。
因为您的意图不明确,我无法真正帮助您了解代码的细节。
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
我需要解决以下问题:
我需要在内存中放入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;
}
}
你对 x86 程序集的要求太高了。
在任何给定的指令中,只能有一个内存操作数。
您的 cmp [si+al],[di+bl]
有两个,因此不会 assemble。
您还使用 cx
作为 2 个循环的循环计数器。这是行不通的。第一个循环完成后 cx
将为 0,即 65536,这意味着外循环 + 内循环将 运行 64k 次(oops)。
因为您的意图不明确,我无法真正帮助您了解代码的细节。
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