80386彙編實現矩陣相乘

題目描述

編寫一個矩陣乘法程序,實現元素爲正整數的矩陣的乘法,規模靈活設置

程序功能:

1、 程序帶有3個命令行參數.依次爲矩陣1數據文件名,矩陣2數據文件名,輸出數據文件名。如下:

程序命令 矩陣1數據文件名 矩陣2數據文件名 輸出文件名

2、 dos窗口中執行命令後將計算結果顯示在屏幕上並保存到輸出文件中。

3、 三個數據文件均以文本的格式存儲了矩陣的數據,例如.

矩陣數據文件的內容爲矩陣內容,數字中間以空格分隔

12 11 6

11 11 7

11 10 7

矩陣2數據文件的內容爲:

2

3

4

則輸出文件的內容爲.

81

83

80,

如果矩陣1的列數和矩陣2的行數不匹配,則報錯。

流程圖

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-ZbLuLWjy-1591538967059)(file:///C:/Users/ROBINV~1/AppData/Local/Temp/msohtmlclip1/01/clip_image002.png)]

程序代碼

include Irvine32.inc 

Read_Text PROTO
Change_to_M PROTO
Cal_M PROTO
Output_File PROTO
GetCommandtail PROTO 

PDWORD TYPEDEF PTR DWORD			
PB TYPEDEF PTR BYTE	
.data
M1 DWORD 10000 DUP (0);三個矩陣
M2 DWORD 10000 DUP (0)
M3 DWORD 10000 DUP (0)
row1 DWORD ?;矩陣行列信息
row2 DWORD ?
col1 DWORD ?
col2 DWORD ?
i1 DWORD ?
i2 DWORD ?
filehandle DWORD ?

now1 PDWORD ?;指針
now11 PDWORD ? 
now2 PDWORD ?
now22 PDWORD ?
now3 PDWORD ?
jump1 DWORD ?
jump2 DWORD ?
start PDWORD ?
row PDWORD ?
col PDWORD ?
buff_tmp PB ?

num DWORD ?
text BYTE 600 DUP(0);輸入命令行
input1 BYTE 200 DUP(0)
input2 BYTE 200 DUP(0)
input PB ?
output BYTE 200 DUP(0)
input1_size DWORD 0
input2_size DWORD 0
output_size DWORD 0
eccx DWORD 0

cnt DWORD 1

wa1 BYTE "Wrong Input!",0
wa2 BYTE "Open File Failed!",0
wa3 BYTE "Can't Calculate!",0
accept BYTE 'The answer matrix is',10,0
buff BYTE 10000 dup(?)
buff_size DWORD 0
.code
main PROC
    mov edx,offset text                                ;讀入命令行
    call GetCommandtail                            
    call Read_Text

    mov al,input1[0]                                   ;文件名是否正常識別
    cmp al,00h
    je err1
    mov al,input2[0]
    cmp al,00h
    je err1
    mov al,output[0]
    cmp al,00h
    je err1

    mov start,offset M1
    mov edx,offset input1
    mov row,offset row1
    mov col,offset col1
    call Change_to_M

    mov start,offset M2
    mov edx,offset input2
    mov row,offset row2
    mov col,offset col2
    call Change_to_M

    mov eax,col1
    cmp eax,row2
    jne err3

    mov edx,offset accept
    call writestring

    call Cal_M

    call Output_File

    exit

    err1:
        mov edx,offset wa1
        call writestring
        exit

    err3:
        mov edx,offset wa3
        call writestring
        exit

main ENDP

;-----------------------------------------------------------------------------------------
;讀取命令行,然後分解
Read_Text PROC
    mov ecx,1
    for1:
        cmp text[ecx],00h                         ;字符串結束
        je break
        cmp text[ecx]," "                         ;出現空格,代表下一個
        je next
        mov al,text[ecx]                          ;EAX低16位爲AX,AX低8位爲AL
        cmp cnt,1
        je input1_in
        cmp cnt,2
        je input2_in
        cmp cnt,3
        je output_in

        next:                                      ;一個文件名完畢,下一個
            inc cnt
            jmp continue

        input1_in:                                ;input1的文件名
            mov esi,input1_size
            mov input1[esi],al
            inc input1_size
            jmp continue

        input2_in:                                ;input2的文件名
            mov esi,input2_size
            mov input2[esi],al
            inc input2_size
            jmp continue

        output_in:                                ;output的文件名
            mov esi,output_size
            mov output[esi],al
            inc output_size
            jmp continue 

        continue:
        inc ecx
    jmp for1
    break:
    ret
Read_Text ENDP
;-----------------------------------------------------------------------------------------
;轉化出矩陣
Change_to_M PROC
    mov input,edx 
    mov eccx,ecx
    mov eax,0                           ;先把eax=0,防止對invailed判斷造成影響
    call openinputfile                  ;打開文件名存在edx中
    cmp eax,invalid_handle_value
    je err2
    mov filehandle,eax
    mov esi,offset buff
    mov ecx,lengthof buff
    clear:                              ;清空緩衝區
        mov ebx,0
        mov [esi],ebx
        add esi,type BYTE
    loop clear    
    mov edx,offset buff
    mov ecx,lengthof buff
    call readfromfile                   ;磁盤文件加載到緩衝區
    mov eax,filehandle
    call closefile

    mov esi,row                         ;從1行1列開始
    mov ebx,[esi]
    inc ebx
    mov [esi],ebx
    mov esi,col
    mov ebx,[esi]
    inc ebx
    mov [esi],ebx                  
    
    mov ecx,0
    Getchar:
        mov esi,start
        cmp buff[ecx],' '               ;空格
        je space
        cmp buff[ecx],0dh               ;回車
        je next
        cmp buff[ecx],10                ;換行
        je enter_
        cmp buff[ecx],00h               ;結束
        je _end

        mov eax,[esi]
        mov edx,10
        mul edx
        mov [esi],eax
        mov eax,0                       ;這裏不賦0的話,後面只是對eax的低位操作,高位不改變,會產生影響
        mov al,buff[ecx]
        sub al,'0'                      ;字符是8位
        add [esi],eax                   ;數組是32位的
        jmp next

        space:
            mov esi,start                ;調試語句
            mov eax,[esi]                ;調試語句

            add start,type DWORD
            mov esi,row
            mov ebx,[esi]
            cmp ebx,1                 ;不是第一行,說明列數已經統計完畢
            jne next
            mov esi,col
            mov ebx,[esi]
            inc ebx
            mov [esi],ebx
            jmp next

        enter_:
            mov esi,start                ;調試語句
            mov eax,[esi]                ;調試語句


            add start,type DWORD
            mov esi,row
            mov ebx,[esi]
            inc ebx
            mov [esi],ebx
            jmp next
        
        _end:
            mov esi,start                ;調試語句
            mov eax,[esi]                ;調試語句
            jmp realend
        
        next:
            inc ecx
            jmp Getchar

        realend:
    ret

    err2:
        mov edx,offset wa2
        call writestring
        exit
Change_to_M ENDP
;-----------------------------------------------------------------------------------------
;矩陣計算
Cal_M PROC
    mov eax,type M1;jump1=DW*col1-
    mov ebx,col1
    mul ebx
    mov jump1,eax

    mov eax,type M1;jump2=DW*col2
    mov ebx,col2
    mul ebx
    mov jump2,eax


    mov edx,offset M1;now1
    mov now1,edx
    mov edx,offset M3;now3
    mov now3,edx

    mov i1,0
    for1:
        mov eax,i1
        cmp eax,row1
        je break1
        mov edx,offset M2;now2
        mov now2,edx
        mov i2,0
        for2:
            mov eax,i2
            cmp eax,col2
            je break2
            mov eax,now1;now11=now1
            mov now11,eax
            mov eax,now2;now22=now2
            mov now22,eax
            mov ecx,col1
            L9:
                mov esi,now11
                mov eax, [esi];[now11]*[now22]
                mov esi,now22
                mov ebx,[esi]
                mul ebx

                mov esi,now3
                add eax,[esi];[now3]+=[now11]*[now22]
                mov [esi],eax
                
                mov eax,now11;now11++
                add eax,type DWORD
                mov now11,eax
                mov eax,now22;now22+=jump2
                add eax,jump2
                mov now22,eax
            loop L9
            mov eax,now3;now3++
            add eax,type DWORD
            mov now3,eax
            mov eax,now2;now2++
            add eax,type DWORD
            mov now2,eax
            inc i2
            jmp for2
        break2:
        mov eax,now1;now1+=jump1
        add eax,jump1
        mov now1,eax
        inc i1
        jmp for1
    break1:

    mov eax,row1;eax=row1*col2
    mov ebx,col2
    mul ebx
    mov num,eax
    ret
Cal_M ENDP
;-----------------------------------------------------------------------------------------
;輸出
Output_File PROC
    mov esi,offset buff
    mov buff_tmp,esi
    mov edx,offset M3
    mov now3,edx
    mov i1,0
    for1:
        mov eax,i1
        cmp eax,row1
        je break1

        mov i2,0
        for2:
            mov eax,i2
            cmp eax,col2
            je break2
            
            mov ecx,0
            mov esi,now3
            mov eax,[esi]
            for3:
                cmp eax,0
                je break3
                inc ecx
                mov edx,0                                ;餘數清0
                mov ebx,10
                div ebx

                add edx,'0'
                push edx
                jmp for3
            break3:

            for4:
                pop eax
                mov esi,buff_tmp
                mov [esi],al
                inc buff_tmp
                inc buff_size
            loop for4

            mov al,' '
            mov esi,buff_tmp
            mov [esi],al
            inc buff_tmp
            inc buff_size

            mov esi,now3
            add esi,type DWORD
            mov now3,esi
            inc i2
            jmp for2
        break2:

        mov al,10
        mov esi,buff_tmp
        mov [esi],al
        inc buff_tmp
        inc buff_size

        inc i1
        jmp for1
    break1:

    mov al,00h
    mov esi,buff_tmp
    mov [esi],al
    inc buff_tmp
    inc buff_size

    mov edx,offset buff
    call writestring

    mov edx,offset output
    call createoutputfile
    cmp eax,invalid_handle_value
    je err2
    mov edx,offset buff
    mov ecx,buff_size
    call writetofile
    

    ret
    err2:
        call writestring
        mov edx,offset wa2
        call writestring
        exit

Output_File ENDP

END main

錯誤記錄

兩個main是不同的!

main PROC一個叫做main的過程開始
main ENDP結束
END main結束程序,main是程序入口,名字是可以自己設置的

int21h是8086

彙編不區分大小寫,導致重名

拼寫錯誤

writestring->writesring

跳太遠

loop循環改成jump

指針定義錯誤

now11 DWORD ?->PDD TYPEDEF PTR DWORD

​ now11 PDD ?

mov eax,[now11]->mov esi,now11

​ mov eax,[esi]

自定義函數未聲明

end main位置

end main放在最後,不要放主過程最後

與保留字重複

for->for1

語法錯誤

縮寫誤用

此時不能縮寫,全寫DWORD

中文字符

中文:換成英文:

命令行位置

讀入命令行首字母爲空

從第2個字符開始讀

忘記賦值

數據段清空

BYTE清空時當成DWORD,導致後面的數據被清零

沒有考慮回車

導致每行末尾數錯誤

文件句柄更改導致關閉失敗

打開文件後eax存儲文件句柄,之後如果用到eax要先把文件句柄存起來,否則會導致文

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章