0%

x86汇编(MASM)实现矩阵乘法

参考《汇编语言 基于x86处理器》(Kip Irvine)并使用了其中库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
INCLUDE Irvine32.inc
maxn=50
.data
fa DWORD ?
fb DWORD ?
fo DWORD ?
buffer BYTE maxn*maxn*12 DUP(0)
bf BYTE 20 DUP(0)
ma DWORD maxn*maxn DUP(0)
mb DWORD maxn*maxn DUP(0)
mc DWORD maxn*maxn DUP(0)
filehandle DWORD ?
eda DWORD ?
m DWORD ?
n DWORD ?
p DWORD ?
q DWORD ?
ERRSTR BYTE "Invalid Input! Matrix Dim ERR",10,0
NEWLINE BYTE 10,0
divisor DWORD 10
.code
ReadMatrix PROC
push ebp
mov ebp,esp
sub esp,16
;打开文件
mov edx,[ebp+8] ;第一个参数,文件名
mov edi,[ebp+12] ;第二个参数,存到内存何处
call OpenInputFile ;打开文件过程
mov filehandle,eax ;存储handle,供Close用

;读文件
mov edx,OFFSET buffer
mov ecx,SIZEOF buffer
call ReadFromFile
mov eda,eax
add eda,OFFSET buffer


;mov edx,OFFSET buffer
;call WriteString

;关文件
mov eax,filehandle
call CloseFile

;处理字符串
mov edx,OFFSET buffer
mov esi,OFFSET buffer
mov DWORD PTR[ebp-12],0 ;计数器,有多少个数
L3:
inc esi
mov al,BYTE PTR [esi]
cmp al,' '
jne L3
mov BYTE PTR [esi],0
mov ecx,esi
sub ecx,edx ;ecx 存即将parse 的字符串长度
call ParseInteger32
mov [edi],eax

mov eax,DWORD PTR[ebp-12]
inc eax
mov DWORD PTR[ebp-12],eax

add edi,4
inc esi

mov al,BYTE PTR [esi]
cmp al,0dh ;0dh 是\r 的ASCII
jne BK
add esi,2 ;过滤 \r 和 \n
BK:
mov edx,esi ;更新edx为下一次要parse 的字符串

cmp esi,eda
jge fin
jmp L3
fin:
mov ecx,0

mov esi,OFFSET buffer
L5:
inc esi
cmp esi,eda
jg F2
mov al,BYTE PTR [esi]
cmp al,10 ;ASCII '\n' 为10
jne L5
inc ecx
jmp L5
F2:
mov DWORD PTR[ebp-4],ecx ;行数 row
mov eax,DWORD PTR[ebp-12] ;总数字数量,被除数的低16位
mov dx,0 ;被除数的高16位数
mov cx,WORD PTR[ebp-4]
div cx
mov WORD PTR[ebp-8],ax
add esp,16
pop ebp
ret
ReadMatrix ENDP

BufferInt PROC
cmp eax,0
jg POS
neg eax
mov BYTE PTR [ecx],'-'
inc ecx
POS:
push edx
push ebx
mov ebx,0
CONT:
mov edx,0 ;高位清零
div divisor ;eax/=10,edx=eax%10
add edx,48 ;ASCII 0 :48
mov BYTE PTR bf[ebx],dl
inc ebx
cmp eax,0
jg CONT
LP:
dec ebx
mov al,BYTE PTR bf[ebx]
mov BYTE PTR [ecx],al
inc ecx
cmp ebx,0
jg LP

pop ebx
pop edx
mov BYTE PTR [ecx],' '
inc ecx
ret
BufferInt ENDP

main PROC
INVOKE GetCommandLine
mov ebp,esp
mov ecx,eax
L1:
inc ecx
mov al,BYTE PTR[ecx]
cmp al,' '
jne L1
L0:
inc ecx
mov al,BYTE PTR[ecx]
cmp al,' '
je L0
mov fa,ecx
L2:
inc ecx
mov al,BYTE PTR[ecx]
cmp al,' '
jne L2
mov BYTE PTR[ecx],0
inc ecx
mov fb,ecx
L22:
inc ecx
mov al,BYTE PTR[ecx]
cmp al,' '
jne L22
mov BYTE PTR[ecx],0
inc ecx
mov fo,ecx

push OFFSET ma
push fa
call ReadMatrix
mov eax,DWORD PTR[esp-16]
mov m,eax
mov eax,DWORD PTR[esp-12]
mov n,eax
add esp,8

push OFFSET mb
push fb
call ReadMatrix
mov eax,DWORD PTR[esp-16]
mov q,eax
mov eax,DWORD PTR[esp-12]
mov p,eax
add esp,8

mov eax,m
cmp eax,p
jne ERR
;----------Matrix Multiply---------
mov ebx,0 ;i
jmp LL2
LL7:
mov esi,0 ;j
jmp LL3
LL6:
mov edi,0 ;k
jmp LL4
LL5:
mov eax,m
imul eax,ebx ;i*m
add eax,esi ;i*m+j
mov edx,DWORD PTR ma[eax*4]

mov eax,DWORD PTR q
imul eax,esi ;j*q
add eax,edi ;j*q+k
mov eax,DWORD PTR mb[eax*4]

imul edx,eax ;val=ma[i*m+j]*mb[j*q+k]

mov eax,q
imul eax,ebx ;i*q
add eax,edi ;i*q+k
mov ecx,DWORD PTR mc[eax*4]

add edx,ecx ;mc[i*q+k]+=val
mov DWORD PTR mc[eax*4], edx
add edi,1 ;++k
LL4:
mov eax,DWORD PTR q
cmp edi,eax
jl LL5
add esi,1
LL3:
mov eax,DWORD PTR m
cmp esi,eax
jl LL6
add ebx,1
LL2:
mov eax,DWORD PTR n
cmp ebx,eax
jl LL7
;----------Matrix OUTPUT-----------
mov ecx,OFFSET buffer
mov ebx,0 ;i
jmp L3
L6:
mov esi,0 ;j
jmp L4
L5:
mov eax,q
imul eax,ebx ;i*q
add eax,esi ;i*q+j
mov eax,DWORD PTR mc[eax*4]
;call WriteInt
call BufferInt
add esi,1
L4:
mov eax,DWORD PTR q
cmp esi,eax
jl L5
;mov edx,OFFSET NEWLINE
;call WriteString
mov BYTE PTR [ecx],13 ;\r
inc ecx
mov BYTE PTR [ecx],10 ;\n
inc ecx
add ebx,1
L3:
mov eax,DWORD PTR n
cmp ebx,eax
jl L6

mov BYTE PTR[ecx],0 ;\0
mov eda,ecx
mov edx,fo
call CreateOutputFile
mov edx,OFFSET buffer ;edx buffer pointer
call WriteString
mov ecx,eda
sub ecx,OFFSET buffer ;ecx buffer_size
call WriteToFile
call CloseFile
jmp NOERR
ERR:
mov edx,OFFSET ERRSTR
call WriteString
NOERR:
INVOKE ExitProcess,0
main ENDP
END main