. : : Assembly Language : : .  |  首页  |  我提出的问题  |  我参与的问题  |  我的收藏  |  消息中心   |  游客  登录  | 
刷新 | 提问 | 未解决 | 已解决 | 精华区 | 搜索 |
  《汇编语言》论坛 ->自由讨论区
  管理员: assembly   [回复本贴] [收藏本贴] [管理本贴] [关闭窗口]
主题 : :  花了近一天,终于把一个朋友的“矩阵乘法”搞定了,大家有兴趣也可以试试  [待解决] 回复[ 4次 ]   点击[ 378次 ]  
zhihuimao
[帖 主]   [ 发表时间:2009-06-04 22:40 ]   [引用]   [回复]   [ top ] 
荣誉值: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的任意数值,可以的话,谁回复一下,如何编写,谢谢!
abob
[第1楼]   [ 回复时间:2009-06-08 11:30 ]   [引用]   [回复]   [ top ] 
荣誉值:169
信誉值:0
注册日期:2008-08-19 16:07
一个实践汇编的小项目,踩踩
abob
[第2楼]   [ 回复时间:2009-06-08 11:31 ]   [引用]   [回复]   [ top ] 
荣誉值:169
信誉值:0
注册日期:2008-08-19 16:07
还没想明白如何输入0~255的任意数值或者0~65535的任意数值,
----------------------
调用中断,输入就行了,和c语言由屏幕输入一个字符串一样。
zzlya
[第3楼]   [ 回复时间:2009-07-23 01:02 ]   [引用]   [回复]   [ top ] 
荣誉值:0
信誉值:0
注册日期:2009-04-03 12:49
头都大了。。。
crazyman
[第4楼]   [ 回复时间:2009-07-24 10:00 ]   [引用]   [回复]   [ top ] 
荣誉值:152
信誉值:3
注册日期:2008-01-24 21:26
牛啦!
需要登录后才能回帖 -->> 请单击此处登录
    Copyright © 2006-2024   ASMEDU.NET  All Rights Reserved