📄 array.asm
字号:
//*********************************************************//
//******** 矩阵相乘 ********//
//*********************************************************//
#include "defBF535.h" //基于BF535
#define Row 5 // 矩阵a的行数
#define Col 5 // 矩阵b的列数
#define Inner 5 // 矩阵a的列数
#define Offset_Len_1 Inner * 2 // 矩阵a一行的长度
#define Offset_Len_2 Col * 2 // 矩阵b一列的长度
#define Num Row*Col // 乘后矩阵的元素个数
.section data_a;
.align 2;
.BYTE2 aArray[] = "input1.dat"; // 从input1.dat中读取矩阵a的元素
.BYTE2 bArray[] = "input2.dat"; // 从input2.dat中读取矩阵b的元素
.BYTE4 cArray[Num]; // 矩阵相乘结果
.section l2_bank0;
.align 2;
.global _MAIN;
_MAIN:
SP.H = 0xFFB0;//设置初始地址值
SP.L = 0x0F00;
I0.H=aArray;//创建矩阵a的索引
I0.L=aArray;
I1.H=bArray;//创建矩阵b的索引
I1.L=bArray;
I2.H=cArray;//创建结果矩阵的索引
I2.L=cArray;
P0=I0;//令P0指向矩阵a的首地址
P1=I1;//令P1指向矩阵b的首地址
P4=Row;//P4记录矩阵a的行数
P5=Col;//P5记录矩阵b的列数
P2=Offset_Len_1;//P2记录矩阵a的行长度
P3=Offset_Len_2;//P3记录矩阵b的列长度
LSETUP(aArray_row_start,aArray_row_end)LC0=P4;//循环一:矩阵a行寻址
aArray_row_start:
P1=I1;//重置P1 使之重新指向矩阵b的首地址 准备进入新一轮循环
LSETUP(bArray_col_start,bArray_col_end)LC1=P5;//循环二:矩阵b列寻址
bArray_col_start:
call Calculate;//调用Calculate函数 R0返回结果
[I2++]=R0;//将R0存入结果矩阵
bArray_col_end : P1+=2;//当此循环结束 P1指向矩阵b下一列的首地址
aArray_row_end : P0=P0+P2;//当此循环结束 P0指向矩阵a下一行的首地址
IDLE;
SSYNC;
_MAIN.END:
Calculate://Calcultate子程序
[--sp]=LC0;
[--sp]=LB0;
[--sp]=LT0;//循环计数器压栈保护
[--sp]=P0;
[--sp]=P1;//指针寄存器压栈保护
A0=0;//清空初始化累加器A0
LSETUP(Cal_start,Cal_end)LC0=P4;//循环三:相乘矩阵相应元素相乘叠加
Cal_start:
R0.L=W[P0];//当前行依次取矩阵a的待乘元素 并赋给数据寄存器R0的低16位
P0+=2;//P0指向矩阵a相应行的下一元素
R0.H=W[P1];//当前列依次取矩阵b的待乘元素 并赋给数据寄存器R0的高16位
P1+=Offset_Len_2;//P1指向矩阵b下一列的对应元素
A0+=R0.L*R0.H(IS);//将两矩阵中待乘元素相乘,并将结果送入累加器A0累加
Cal_end: NOP;
R0=A0;//将累加结果传递给数据寄存器R0
P1=[sp++];
P0=[sp++];//指针寄存器弹栈恢复
LT0=[sp++];
LB0=[sp++];
LC0=[sp++];//循环计数器弹栈恢复
RTS;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -