文章目錄
題目描述
編寫一個矩陣乘法程序,實現元素爲正整數的矩陣的乘法,規模靈活設置
程序功能:
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要先把文件句柄存起來,否則會導致文