|
主题 : : 花了近一天,终于把一个朋友的“矩阵乘法”搞定了,大家有兴趣也可以试试 [待解决] |
回复[ 4次 ]
点击[ 378次 ] | |
荣誉值:0
信誉值:0
注册日期:2009-05-27 19:28 |
;题目:
;(1) 输入m*n矩阵和n*m矩阵的数据并给出提示信息,要求独占一行。
;(2) 求两矩阵的积。
;(3) 输出矩阵和矩阵的积。
;**************************************************************************
DATA SEGMENT ;数据段定义
INFORMATION DB "Please enter the matrix1!The array is 3*3!$" ;提示说明(位置:从0开始)——共43字符
MATRIX1 DB 9 DUP(?),"$" ;矩阵1 (位置:2BH开始)——共10字符
MATRIX2 DB 9 DUP(?),"$" ;矩阵2 (位置:35H开始)——共10字符
RESULT DW 9 DUP(?),"$" ;矩阵相乘结果 (位置:3FH开始)——共19字符
MATRIX3 DD 9 DUP (0) ;保存转换后需要显示的ascii码值 (位置:53H开始)——共36字符
M1 DB "The array1:$" ;提示信息(位置:77H开始)——共12字符
M2 DB "The array2:$" ;(位置:83H开始)——共12字符
M3 DB "Array1*Array2:$" ;(位置:8FH开始)——共15字符
DATA ENDS
;**************************************************************************
stack segment
dw 32 dup (0)
stack ends
;**************************************************************************
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ss:stack
START:
MOV AX,DATA
MOV DS,AX
mov ax,stack
mov ss,ax
mov sp,40h
mov dx,offset information ;取信息提示地址偏移量
call show ;调用show过程显示提示信息
call newline ;调用newline回车换行
mov dx,offset m1 ;提示输入矩阵1
call show ;调用show显示M1的字符信息
call newline ;回车换行
MOV CX,9
mov si,0
INPUT1:
MOV AH,1 ;键盘输入并回显
INT 21H
sub al,30h
MOV matrix1[si],al
INC si
mov dl,20h ;显示空格
mov ah,2
int 21h
mov ax,cx
mov dl,3
div dl
cmp ah,1
jnz j
call newline
j:LOOP INPUT1
call newline
mov dx,offset m2 ;提示输入矩阵2
call show ;调用show显示M1的字符信息
call newline ;回车换行
mov cx,9
mov si,0
INPUT2:
MOV AH,1 ;键盘输入并回显
INT 21H
sub al,30h
MOV matrix2[si],al
INC si
mov dl,20h ;显示空格
mov ah,2
int 21h
mov ax,cx
mov dl,3
div dl
cmp ah,1
jnz k
call newline
k:LOOP INPUT2
call newline
MOV BX,OFFSET MATRIX1
MOV SI,OFFSET MATRIX2
MOV DI,OFFSET RESULT
MOV CX,3 ;因为Matrix1为三行,所以循环3次调用子程序LINEMULCOLOUM
mulresult:
CALL LINEMULCOLOUM ;调用矩阵1某行和矩阵2的列相乘子程序
add bx,3 ;指向Matrix1的下一行
add di,6 ;运算结果内存单元加3,保存下面三个值
loop mulresult
LEA DX,M3 ;显示M3的字符串信息
call show
call newline
mov cx,9
mov di,0
mov si,offset matrix3
showstr:
mov ax,[result+di]
call dtoc
add di,2
add si,4
mov ax,cx
mov dl,3
div dl
cmp ah,1
jnz m
call newline
m:loop showstr
MOV Ax,4C00H
INT 21H
;过程名称:LINEMULCOLOUM
;功能:实现M1矩阵的一行和M2矩阵的三列相乘
;入口参数:(BX)=M1矩阵第一行第一个数的偏移地址
; (SI)=M2矩阵第一列第一个数的偏移地址
; (DI)=要保存的结果的第一行第一个数的偏移地址
;出口参数:ds:[di]中保存结果
LINEMULCOLOUM PROC NEAR ;矩阵相乘子程序
PUSH dx ;保护寄存器
push cx
push si
push di
push bx
mov cx,3 ;设定外层循环次数
r: push cx ;保护外层循环要用到的寄存器不被内层循环破坏
push si
push di
push bx
s: MOV CX,3 ;设置内层循环次数
mov dx,0
t: mov al,[bx] ;取出Matrix1行中的第一个数据
IMUL byte ptr [si] ;把Matrix1的行和Matrix2的列相乘
ADD DX,AX ;把相乘结果存放到DX寄存器
inc bx ;取Matrix1行中的下一个数据
add si,3 ;取Matrix2的列的下一个数据
LOOP t ;内层循环
mov [di],dx ;把Matrix1行和Matrix2列相乘的结果保存到内存中
pop bx ;恢复外层循环BX寄存器的值
pop di ;恢复外层循环DI寄存器的值
add di,2 ;DI寄存器指向要保存的结果的下一个位置
pop si ;恢复外层循环SI寄存器的值
inc si ;让SI指向M2的下一列
pop cx ;恢复外层循环计数器
loop r ;外层循环
pop bx ;恢复外层循环前保存的寄存器值
pop di
pop si
pop cx
pop dx
RET ;返回主程序
LINEMULCOLOUM ENDP
;过程名称:show
;功能:显示字符串
;入口参数:DS:DX=需要输出字符串的首地址,字符串以字符'$'为结束标志
;出口参数:无
show proc
push ax
mov ah,9 ;调用9号功能,实现字符串输出
int 21h
pop ax
ret
show endp
;过程名称:newline
;功能:实现回车换行操作
;入口参数:无
;出口参数:无
newline proc
push ax
push dx
mov dl,0dh
mov ah,2
int 21h
mov dl,0ah
mov ah,2
int 21h
pop dx
pop ax
ret
newline endp
;过程名称:dtoc
;功能:将word型数据转变成表示十进制数的字符串,字符串以0为结尾符。
;入口参数:(AX)=word型数据,DS:SI指向字符串的首地址
;出口参数:无
dtoc proc
mov bp,sp
push si
push ax
push dx ;压栈保护dx、bx和cx寄存器中的值
push bx
push cx
mov bx,10
mov si,0 ;设定除数为10
u:mov dx,0 ;设定被除数的高16位为0
div bx
add dl,30h ;把余数dx(肯定在dl中)转变为ascII码字符
push dx ;把dx压栈,以便逆序保存获得的ascii码
inc si ;把获得的ascii码的个数加1
mov cx,ax ;把商放到cx中
jcxz v ;若cx(即商)为0,则转移到w标号处执行
jmp u ;商不为0,跳转到v继续执行
v:mov cx,si ;把获得的ascii码的位数送到cx中,作为下一个循环的计数器
mov si,0
mov bx,[bp+2] ;把si置0,以备循环保存ascii码
w:pop dx ;取出栈中保存的ascii码
mov [bx+si],dl ;送到内存单元
mov ah,2 ;把得到的字符显示出来
int 21h
inc si ;变址指针加1
loop w ;循环跳转到P处
mov dl,20h
mov ah,2
int 21h ;显示空格
pop cx ;恢复子程序用到的寄存器值
pop bx
pop dx
pop ax
pop si
ret
dtoc endp
code ends
end start
;程序应该还可以压缩一下,不过实在脑壳有点晕,贴上来,下次有机会再去压缩了。
;我写的这个程序有个缺陷:就是矩阵数字只能输入个位数,还没想明白如何输入0~255的任意数值或者0~65535的任意数值,可以的话,谁回复一下,如何编写,谢谢! | | |