汇编语言中的二维数组

时间:2021-07-07 03:24:40

标签: c++ assembly multidimensional-array masm emu8086

我正在尝试将我的 C++ 代码转换为 MASM 代码。 我在处理二维数组时遇到了麻烦。

请帮帮我!

问题:求最长公共子串

我的 C++ 代码:

#include<stdio.h>
#include<string.h>
char s[20],t[20];
int b[20][20];
int n,m;
void substr(int i,int j) {
    if (i&&j) {
        if (b[i][j]==1) {
            substr(i-1,j-1);
            printf ("%c",s[i]);
        } else if (b[i][j]==2)
            substr(i-1,j);
        else substr(i,j-1);
    }
}
int main() {
    int f[20][20];
    gets(s+1);
    gets(t+1);
    m=strlen(s+1);
    n=strlen(t+1);
    for (int i=1; i<=m; i++)
        for (int j=1; j<=n; j++)
            if (s[i]==t[j]) {
                f[i][j]=f[i-1][j-1]+1;
                b[i][j]=1;
            } else {
                if (f[i-1][j]>=f[i][j-1]) {
                    f[i][j]=f[i-1][j];
                    b[i][j]=2;
                } else {
                    f[i][j]=f[i][j-1];
                    b[i][j]=3;
                }
            }
    printf("\n::: OUTPUT :::\n");
    if(n==0){
        printf("There is no common substring of S and T!");
    } else {
        printf("The longest substring: \"");
        substr(m,n);
        printf("\".");
    }
    return 0;
}

还有我的 ASM 代码:

    .model small
; input s, m is lenght of s
    input macro s,m 
        push ax
        push dx                                  
        mov ah, 0Ah 
        lea dx, s
        int 21h                 
        mov al, s + 1 
        xor ah, ah
        mov m, ax
        pop ax
        pop dx     
    endM 
   
    substr macro i,j
        push ax
        push bx
        push cx
    if_s:
    loopij:
        cmp i,0
        jne halt
        cmp j,0
        jne halt
        if_2s:
            cmp b[i][j],1 
            jne else_if
            dec i
            dec j
            substr(i,j)
            lea dx, s[i]
            mov ah, 9
            int 21h
            jmp halt
         else_ifs:
             cmp b[i][j],2
             jne else
             dec i
             substr(i,j)
             jmp halt
          elses:          
             dec j
             substr(i,j)
             jump halt
        jmp loopij 
        ret       
     halt:
     pop ax
     pop bx
     pop cx
endm
.stack 100h
.data 
    newline db 10,13, "$"
    s db  255, ?, 255 dup(0)
    t db  255, ?, 255 dup(0)
    m dw ?
    n dw ?
    i dw ?
    j dw ?
    arr1 db i dup(0)
         db j dup (0)
    arr2 db i dup (0)
         db j dup (0)
.code  
main proc        
    mov  ax,@data
    mov  ds,ax

    input s, m
    call newln
    input t, n
    call newln

    xor ax, ax
    inc ax
    mov i, 2
loopi:
    add ax, m
    cmp i, ax
    ja outloopi
    mov j, 2
loopj:
    mov ax, 1
    add ax, n 
    cmp j, ax
    ja outloopj
    if_:
        mov dx, s[i]
        cmp dx, t[j]
        jne else
        mov cx, f[i-1][j-1]
        mov f[i-1][j-1], cx
        mov b[i][j],1
    else:
        else_if:
            cmp f[i-1][j], f[i][j-1]
            jb else_else
            mov cx,f[i-1][j] 
            mov f[i][j], cx
            mov b[i][j],2
        else_else:
            mov cx,f[i][j-1] 
            mov f[i][j], cx                
            mov b[i][j],3
    jmp loopj
outloopj:
    jmp loopi 
outloopi:       
    substr m, n

    mov  ax,4ch
    int  21h  
main endp

newln proc
    mov ah, 9
    lea dx, newline
    int 21h
    ret
newln endp

end main

如何在 ASM 中声明一个二维数组?

如何在 ASM 中处理二维数组?

在这种情况下,我可以将二维数组转换为一维数组吗?

非常感谢!

1 个答案:

答案 0 :(得分:1)

<块引用>

如何在 ASM 中声明一个二维数组?
如何在 ASM 中处理二维数组?

让我们以 3 X 4 矩阵为例,即 3 行 x 4 列。

(0,0) (0,1) (0,2) (0,3)    <- 1st row
(1,0) (1,1) (1,2) (1,3)    <- 2nd row
(2,0) (2,1) (2,2) (2,3)    <- 3rd row

  ^     ^     ^     ^
 1st   2nd   3rd   4th
 col   col   col   col

假设元素为字节大小,只需写入:

MyArray db 3*4 dup (0)

这会留出一个 12 字节的内存块。它是一个二维数组的特殊性质纯粹来自于你,程序员,将如何与它交互并解释它的内容。

行顺序查看矩阵:

| MyArray
|
<        row 0        > <        row 1        > <        row 2        >
----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
(0,0) (0,1) (0,2) (0,3) (1,0) (1,1) (1,2) (1,3) (2,0) (2,1) (2,2) (2,3)

以下是您如何寻址数组中的任何元素。

OffsetInTheArray = (RowIndex * NumberOfColumns + ColumnIndex) * BytesPerElement

emu8086 风格的赋值MyArray[Row][Col] = 1

mov     ax, Cols      ; CONST, (Cols equ ...)
mul     Row
add     ax, Col
;;;shl     ax, 1      ; Only for word-sized elements
mov     bx, ax
mov     byte ptr MyArray[bx], 1

列顺序查看矩阵:

| MyArray
|
<     col 0     > <     col 1     > <     col 2     > <     col 3     >
----- ----- ----- ----- ----- ----- ----- ----- ----- ----- ----- -----
(0,0) (1,0) (2,0) (0,1) (1,1) (2,1) (0,2) (1,2) (2,2) (0,3) (1,3) (2,3)

以下是您如何寻址数组中的任何元素。

OffsetInTheArray = (ColumnIndex * NumberOfRows + RowIndex) * BytesPerElement

emu8086 风格的赋值MyArray[Row][Col] = 1

mov     ax, Rows      ; CONST, (Rows equ ...)
mul     Col
add     ax, Row
;;;shl     ax, 1      ; Only for word-sized elements
mov     bx, ax
mov     byte ptr MyArray[bx], 1

与二维数组的问题无关,但非常重要。

<块引用>
input macro s,m 
  push ax
  push dx                                  
  ...
  pop ax
  pop dx
endM 

您必须以相反的顺序恢复这些寄存器!堆栈是后进先出 (LIFO) 结构:

push    ax
push    dx
...
pop     dx
pop     ax

<块引用>
substr macro i,j
  push ax
  push bx
  push cx
  ...
  pop ax
  pop bx
  pop cx
endm

在这里,您还必须以相反的顺序恢复这些寄存器。同样重要的是,看到 substr 是一个递归过程,你不应该把它变成一个宏。


<块引用>
cmp i,0
jne halt
cmp j,0
jne halt

此代码段不是 if (i&&j) 的正确翻译。恰恰相反:

cmp     i, 0
je      halt
cmp     j, 0
je      halt

<块引用>
mov  ax,4ch
int  21h  

DOS 函数号进入 AH 寄存器。您的指令将其放入 AL

mov     ax, 4C00h   ; DOS.TerminateWithReturnCode
int     21h

<块引用>
lea dx, s[i]
mov ah, 9
int 21h

这不会像在 printf ("%c",s[i]) 中那样工作。 DOS.PrintString 函数 09h 期望 DX 指向以 $ 结尾的字符串。另一个 DOS 函数可以做到这一点:

mov     bx, i
mov     dl, s[bx+2] 
mov     ah, 02h     ; DOS.PrintCharacter
int     21h

如果您想知道 +2,那么您已经通过使用 DOS.BufferedInput 函数 0Ah 获得了字符串 s,该函数返回了缓冲区偏移量 2 处的字符你命名为s。您必须在许多地方注意这一点。

接下来是问题的快速解决方案:

  db      255, 0
s db      255 dup (0)
  ...
  lea     dx, s-2
  mov     ah, 0Ah   ; DOS.BufferedInput
  int     21h

此代码中还有其他问题,但我认为通过上述所有内容,您应该能够编写第一次尝试。使用该代码,您可以随时返回...