我正在尝试将我的C++代码转换为MASM代码。 我在使用 2D 阵列时遇到了麻烦。
请帮帮我!
问题:查找最长的常见子字符串
我的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中使用2D阵列?
在这种情况下,我可以将二维数组转换为一维数组吗?
多谢!
如何在 ASM 中声明 2D 数组?
如何在 ASM 中使用 2D 数组?
让我们以 3 X 4 矩阵为例,即 3 行乘 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
分配MyArray[Row][Col] = 1
emu8086 样式:
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
分配MyArray[Row][Col] = 1
emu8086 样式:
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
与有关2-D数组的问题无关,但仍然非常重要。
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获得了字符串s。缓冲输入函数 0Ah,它已从您命名为 s的缓冲区返回偏移量 2 处的字符。你将不得不在许多地方注意这一点。
接下来是问题的快速解决方案:
db 255, 0
s db 255 dup (0)
...
lea dx, s-2
mov ah, 0Ah ; DOS.BufferedInput
int 21h
这段代码中还有其他问题,但我认为通过上述所有内容,您应该能够编写第一次尝试。有了这段代码,你总是可以回来的...