目录

  • 工程简介
  • 源代码
    • C代码
    • 汇编源代码
  • 调试结果

工程简介

使用ARM汇编语言,计算两个二维数组A和B的卷积,通过软件仿真验证。其中A为6×6矩阵:
[ 0 x 23 0 x 25 0 x 27 0 x 85 0 x 86 0 x 87 0 x 33 0 x 35 0 x 35 0 x 95 0 x 95 0 x 98 0 x 44 0 x 45 0 x 44 0 x A 5 0 x A 6 0 x A 7 0 x D 5 0 x D 6 0 x D 7 0 x 68 0 x 69 0 x 7 A 0 x F D 0 x F F 0 x F E 0 x 42 0 x 43 0 x 43 0 x E A 0 x E B 0 x E C 0 x 55 0 x 56 0 x 56 ] \begin{bmatrix} 0\mathrm{x}23 & 0\mathrm{x}25 & 0\mathrm{x}27 & 0\mathrm{x}85 & 0\mathrm{x}86 & 0\mathrm{x}87\\ 0\mathrm{x}33 & 0\mathrm{x}35 & 0\mathrm{x}35 & 0\mathrm{x}95 & 0\mathrm{x}95 & 0\mathrm{x}98\\ 0\mathrm{x}44 & 0\mathrm{x}45 & 0\mathrm{x}44 & 0\mathrm{x}A5 & 0\mathrm{x}A6 & 0\mathrm{x}A7\\ 0\mathrm{x}D5 & 0\mathrm{x}D6 & 0\mathrm{x}D7 & 0\mathrm{x}68 & 0\mathrm{x}69 & 0\mathrm{x}7A\\ 0\mathrm{x}FD & 0\mathrm{x}FF & 0\mathrm{x}FE & 0\mathrm{x}42 & 0\mathrm{x}43 & 0\mathrm{x}43\\ 0\mathrm{x}EA & 0\mathrm{x}EB & 0\mathrm{x}EC & 0\mathrm{x}55 & 0\mathrm{x}56 & 0\mathrm{x}56\end{bmatrix} ⎣ ⎡​0x230x330x440xD50xFD0xEA​0x250x350x450xD60xFF0xEB​0x270x350x440xD70xFE0xEC​0x850x950xA50x680x420x55​0x860x950xA60x690x430x56​0x870x980xA70x7A0x430x56​⎦ ⎤​

卷积核B为3×3矩阵:
[ 1 2 1 0 0 0 − 1 − 2 − 1 ] \begin{bmatrix} 1 & 2 & 1\\ 0 & 0& 0\\ -1 & -2 & -1\end{bmatrix} ⎣ ⎡​10−1​20−2​10−1​⎦ ⎤​

卷积步长为1,padding为0,输出的矩阵为4×4大小

编译环境:Keil 5.37,芯片为Samsung S3C2410A,ARM核;编译器为Arm Compiler V5.06,使用Simulator软件仿真。

⚠️ 注意:上述矩阵尺寸可以在代码中自行修改算法是相同的

⚠️ 注意:使用Keil 5.37及以上版本安装包不自带Arm Compiler V5,需要手动安装。具体方法:下载旧版安装包,提取里面的V5编译器文件夹至当前Keil安装路径下,并在Keil File Extensions内手动添加。

源代码

C代码

C代码与汇编代码算法对应,编译环境:gcc;汇编结果可用C验证。

#include <stdio.h>
#include <stdint.h>int main() {uint16_t A[6][6] = {{0x23, 0x25, 0x27, 0x85, 0x86, 0x87},{0x33, 0x35, 0x35, 0x95, 0x95, 0x98},{0x44, 0x45, 0x44, 0xA5, 0XA6, 0XA7},{0xD5, 0XD6, 0XD7, 0X68, 0X69, 0X7A},{0XFD, 0XFF, 0XFE, 0X42, 0X43, 0X43},{0XEA, 0XEB, 0XEC, 0X55, 0X56, 0X56}};int16_t kernel[3][3] = {{1, 2, 1},{0, 0, 0},{-1, -2, -1}};int16_t c[4][4] = {0};int i, j, k, l;int16_t sum;for (i = 0; i < 4; i++) {for (j = 0; j < 4; j++) {sum = 0;for (k = 0; k < 3; k++) {for (l = 0; l < 3; l++) {sum += kernel[k][l] * A[i+k][j+l];}}c[i][j] = sum;}}// for (k = 0; k < 4; k++) {//     for (l = 0; l < 4; l++) {//         printf("%d ", c[k][l]);//     }//     printf("\n");// }return 0;
}

汇编源代码

使用简单直接的汇编代码计算卷积,算法对应上述C语言代码。r4r5r6r7 作为for 循环索引,r8r9r10 各保存二维矩阵数据基地址、卷积核数据基地址、输出数据基地址。其余寄存器用到r11r12 及堆栈(栈顶指针 r13 需要初始化赋值)。

⚠️ 注意:DCD 是按字(32位)对齐的

DATA_SIZE    EQU 6
KERNEL_SIZE EQU 3
OUTPUT_SIZE EQU 4AREA DEMO, CODE, READONLYENTRYSTARTMOV r4, #0                  ; row of data, iMOV r13, #2000              ; initialize the stack sizeLDR r8, =DATA               ; r8, address of dataLDR r9, =KERNEL               ; r9, address of kernelLDR r10, =OUTPUT            ; r10, address of outputFOR_ROWMOV r5, #0                   ; column of data, jFOR_COLUMNMOV r6, #0                 ; row of kernel, kGET_KERNEL_ROWMOV r7, #0                  ; column of kernel, lGET_SUM; Get the dataADD r11, r4, r6               ; r11 = i + kMOV r12, #DATA_SIZEMUL r11, r12, r11         ; r11 = (i + k) * 6ADD r11, r11, r5           ; r11 = (i + k) * 6 + jADD r11, r11, r7          ; r11 = (i + k) * 6 + j + lMOV r12, #4MUL r11, r12, r11         ; *4LDR r11, [r8, r11]          ; data in r11PUSH {r11}                 ; push data to stack; Get the kernelMOV r12, #KERNEL_SIZEMUL r12, r6, r12           ; r12 = k*3ADD r12, r12, r7            ; r12 = k*3 + lMOV r11, #4MUL r12, r11, r12LDR r12, [r9, r12]         ; get the kernelPOP {r11}MUL r12, r11, r12          ; r12 = kernel * dataPUSH {r12}                    ; push the result to stack; Calculate the resultMOV r11, #4MUL r12, r4, r11         ; r12 = i * 4ADD r12, r12, r5          ; r12 = (i * 4) + jMUL r12, r11, r12          ; get the offsetLDR r11, [r10, r12]POP {r12}ADD r12, r11, r12           ; sum += resultPUSH {r12}MOV r11, #4MUL r12, r4, r11          ; r12 = i * 4ADD r12, r12, r5          ; r12 = (i * 4) + jMUL r12, r11, r12          ; get the offset again; Store the resultPOP {r11}STR r11, [r10, r12]ADD r7, r7, #1CMP r7, #KERNEL_SIZEBMI GET_SUMADD r6, r6, #1CMP r6, #KERNEL_SIZEBMI GET_KERNEL_ROWADD r5, r5, #1CMP r5, #OUTPUT_SIZEBMI FOR_COLUMNADD r4, r4, #1CMP r4, #OUTPUT_SIZEBMI FOR_ROWDATA  DCD 0x23, 0x25, 0x27, 0x85, 0x86, 0x87DCD 0x33, 0x35, 0x35, 0x95, 0x95, 0x98DCD 0x44, 0x45, 0x44, 0xA5, 0xA6, 0xA7DCD 0xD5, 0xD6, 0xD7, 0x68, 0x69, 0x7ADCD 0xFD, 0xFF, 0xFE, 0x42, 0x43, 0x43DCD 0xEA, 0xEB, 0xEC, 0x55, 0x56, 0x56KERNEL  DCD 1, 2, 1DCD 0, 0, 0DCD -1, -2, -1OUTPUT  DCD 0, 0, 0, 0DCD 0, 0, 0, 0DCD 0, 0, 0, 0DCD 0, 0, 0, 0END 

调试结果

使用软件仿真可能需要给对应地址读写、执行的权限,“Initialization File”内手动添加map.ini,形如:

map 0x0000, 0xFFFFF exec read write


查看输出数据,在Memory1下设置观察0x184地址数据,可用前述C语言代码计算结果进行比对。


ARM汇编实现二维卷积/图像卷积(汇编语言)相关推荐

  1. 二维随机变量函数卷积公式的推导

    二维随机变量函数卷积公式的推导 @(概率论) 给定Z=g(x,y)Z = g(x,y) 通常需要求FZ(z),fZ(z)F_Z(z),f_Z(z) 这里是由两个变元依据关系映射到一个变元,因此,求得F ...

  2. 两张二维人物图像互相换脸代码

    之前看了一篇介绍两张二维人物图像互相换脸代码:http://www.cnblogs.com/wm123/p/5370064.html,但是配置环境挺麻烦文章没讲清楚,而且代码有问题,特此重新写个清楚的 ...

  3. 字符串生成二维码图像(C++,Qt)

    字符串转换二维码图像

  4. IDL 二维数组/图像的Sen斜率实现

    参考文献<基于Sen+Mann-Kendall 的北京植被变化趋势分析> 针对二维数组/图像: function Sen_slope,x1,y1,x2,y2s = (y2 - y1)/(x ...

  5. 神经网络 pytorch 分类二维矩阵图像和一维向量的方法

    在网上找资料的过程中,发现并没有特别细致的讲解分类图像和分类一维向量的做法,导致我捅咕了有几天才弄明白,可能使我比较菜吧......现在在这里记录一下. 首先需要明确,前文我们已经讲解了包装数据集的方 ...

  6. 数字图象处理之二维码图像提取算法(九)

    经过对二维条码的预处理过程,去除了条码中包含的大部分背景信息,初步定定位了QR条码,实现了对二维条码的滤波和二值化处理.但是要提取QR码中的码字信息,还需要经过下面三个步骤: (1) 利用QR码符号特 ...

  7. 将一维数据(序列)转化为二维数据(图像)的方法汇总GAFS, MTF, Recurrence plot,STFT

    将一维序列数据转化为二维图像数据的方法汇总 详细 全面 一.背景 二.方法介绍 格拉米角场 GAFs 原理 实现步骤 调用示例 马尔可夫变迁场 MTF 原理 实现步骤 调用示例 递归图 Recurre ...

  8. 一维码和二维码图像的识别

    1.步骤 (1) 提取图像中条码区 (2) 识别条码 2.示例 2.1.一维码的识别 图1.1原图 图1.2提取条码区 图1.3识别结果 2.2.二维码的识别 图2.1原图 图2.2提取条码区 图2. ...

  9. arm汇编学习(二)

    一.STMFD SP!,{R4-R7,R11,LR} 表示依次把R4-R7,R11,LR放入SP中,LR在高位 参考: http://blog.chinaunix.net/uid-26435987-i ...

最新文章

  1. ASP.NET 获取IIS应用程序池的托管管道模式
  2. [开源] .NETCore websocket 即时通讯组件---ImCore
  3. Java文件流输入输出
  4. Struts2.5版本之后Tomcat启动报错问题
  5. Scala模式匹配细节说明
  6. 京东扳回一城,拼多多该小心了?
  7. hadoop安装hive及配置mysql_Hadoop系列之Hive(数据仓库)安装配置
  8. 使用JavaScript中的示例编号MAX_VALUE属性
  9. GridView控件中的一些常见问题
  10. 前端综合性文档和教程总结(持续更新)
  11. java 多线程 异步调用
  12. 八、IO优化(7)减少IO竞争
  13. 脚本实现为一系列账号生成随机密码
  14. 脚本之家python专题_一个简单的python读写文件脚本
  15. 基于java的电子政务网的设计及开发
  16. VSFTPD (500 Illegal PORT command 500 OOPS: vsf_sysutil_bind) 错误解决方法
  17. 视频会议软件 Zoom会议客户端
  18. Knowledge Representation笔记
  19. PS小白怎么学会更换材质效果
  20. 设计原则3: 不要和陌生人说话.

热门文章

  1. Question2Answer插件:qa Connect
  2. word文件不小心被删怎么恢复
  3. java 10进制 掩码运算_ipv6子网掩码计算java
  4. Ubuntu 12.04编译mt6582错误 - Tracy Mcgrady的专栏 - 博客频道 - CSDN.NET awk: line 4: function strtonum never def
  5. 自己做量化交易软件(11)通通量化AI框架的核心--框架结构
  6. latex常用语法笔记
  7. Flex minWidth minHeight
  8. golang 依赖注入 dig详解
  9. python内置函数range(),Python内置函数-range()和xrange()
  10. 使用CSS3滤镜让图片反转颜色