文章目录

  • 汇编语言程序设计的步骤
  • 顺序程序设计
  • 分支程序设计
  • 循环程序设计
  • 子程序设计
    • 寄存器传递参数方式
    • 存储区域传递参数方式
    • 堆栈传递参数方式

汇编语言程序设计的步骤

① 合理地分配存储器资源,将前述的目标系统‘数据结构模型’表示到各存储器单元。

② CPU寄存器数量有限,在程序中,大多数操作都要使用寄存器;并且有的操作使用特定的寄存器(如堆栈操作使用SP/R13等),程序中要合理分配各寄存器的用途。

用计算机语言,对数据结构模型和流程图表示的算法进行准确地描述。

① 语法调试:排除程序中的语法错误。

② 功能调试:保证程序的逻辑功能正确性。

用文档形式记录说明程序的功能、使用方法、程序结构、算法流程等每一个阶段的工作。 把解题的方法、步骤用框图形式表示。如果问题比较复杂,那么可以逐步细化,直到每一框图可以容易编程为止。流程图不仅便于程序的编制,且对程序逻辑正确性也比较容易查找和修改。

顺序程序设计

顺序程序是一种最简单的程序结构,也称为直线程序,它的执行自始自终按照语句的先后顺序进行。这种结构的流程图,除了有一个起始框,一个终止框外,就是若干执行框。

例:试编制一程序,完成10+3的操作。

AREA  ARMex, CODE, READONLY  ; 代码段名ARMex
ENTRY                   ; 程序的入口
CODE 32startMOV R0, #10     ; 将立即数10存入寄存器R0MOV  R1, #3      ; 将立即数3存入寄存器R1ADD   R0, R0, R1  ; R0 = R0 + R1
stopMOV R0, #0x18       ; 这三条指令是ADS调试环境特约LDR    R1, =0x20026   ;程序运行结束返回编译器调试环境SWI     0x123456END             ; 结束

分支程序设计

许多实际问题需要根据不同的情况作出不同的处理。在程序中,针对不同的情况把不同的处理方法编制成各自的处理程序段,运行时由机器根据当时的条件自动作出判断,选择执行相应的处理程序段。这样的程序结构中,计算机不再完全按指令存储的顺序执行,称之为分支。分支程序使用转移指令B、子程序调用指令BL或带状态转移指令BX来实现。

例:给定以下符号函数:

任意给定值,假定为-25,存放在x单元,函数值存放在y单元;要求根据x中的值来确定y的值。

 AREA symbol, CODE, READONLY ; 代码段的名字 symbolENTRY           ; 程序的入口CODE32startLDR   R0, =x ; 加载数据段中的变量x地址,存入R0LDR   R1, =y ; 加载数据段中的变量y地址,存入R1LDR R2, [R0] ; 加载变量x的值,存入R2compareCMP R2, #0 ; 将R2的值与0作比较BEQ ZERO ; 如果R2等于0,那么转向标号ZERO处BGT PLUS ; 如果R2大于0,那么转向标号PLUS处MOV R3, #-1 ; 否则,R2小于0,将-1存入R3中B stopZEROMOV R3, #0 ; R2等于0,将0存入R3中B stopPLUSMOV R3, #1 ; R2大于0,将1存入R3中; 续上段代码stop STR R3,  [R1]MOV R0,  #0x18 LDR R1, =0x20026SWI 0x123456AREA Data, DATA, READWRITEx DCD -25y DCD 0END

循环程序设计

顺序程序和分支程序中的指令每次运行最多只执行一次。在实际应用中重复地做某些事的情况很多,这也是计算机最擅长的工作方式。重复地执行某些指令,最好用循环程序来实现。
循环程序的结构—重复地执行同一种运算,直到某种条件满足。

建立循环初始值。如设置地址指针、计数器、其他循环参数的起始值等。循环程序的主体业务代码,可以是一个顺序程序、分支程序或另一个循环程序。 为执行下一个循环而修改某些参数,尤其循环控制变量的修改等。

条件控制循环:通过判断循环终止条件是否已成立,控制循环。判断循环结束条件是否成立,决定是否继续循环。

例如:计数控制循环;通过计数循环次数,判断是否已达到预定次数,控制循环。对循环结束进行适当处理;有的循环程序可以没有这部分。

用计数控制循环适用于已知循环次数的循环程序设计

例:从x单元开始的30个连续字单元中存放有30个无符号数,从中找出最大者送入y单元中。

分析:

根据题意,把第一个数先送入Rx寄存器,将Rx中的数与后面的29个数逐个进行比较,如果Rx中的数较小,则将该较大的数送入Rx ;继续与余下的数据逐个比较。在比较过程中, Rx中始终保持较大的数,共计比较29次,则最终Rx中保留了最大数,最后把Rx中的数(最大者)送入y单元。

 AREA  max, CODE, READONLY       ; 代码段的名字 maxENTRY                               ; 程序的入口CODE32
num EQU 29                   ; 比较的次数
startLDR    R0,  =x           ; R0指向源数据块xLDR   R1,  =y           ; R1指向单元yLDR R2,  =num      ; R2作为计数器LDR    R3,  [R0]        ; 将源数据块x中第一个数加载到R3中
compareADD  R0, R0, #4       ; 每进行一次比较,将R0指针地址加4LDR  R4, [R0]          ; 依次将源数据块x中下一个数加载到R4中CMP  R3, R4             ; 比较R3和R4中数的大小 MOVCC  R3,  R4          ; 如果R3小于R4,则将较大的数送入R3中SUBS R2,  R2,  #1       ; 计数器值减1BNE  compare           ; 如果不为0,那么继续跳到compare执行STREQ   R3,  [R1]          ; 如果为0,那么循环比较结束,R3是最大的数; 并且将R3中的数加载到R1指向的单元(即y)中 stopMOV r0, #0x18LDR    r1, =0x20026       SWI 0x123456        AREA  Data, DATA, READWRITE
x   DCD 73,59,61,34,81,107,225,231,54,43DCD 100,35,1,42,222,254,34,71,100,31DCD 33,119,13,44,18,147,55,244,97,3
y   DCD 0END

② 适用于已知循环条件的循环程序设计

适用于无法确定循环次数,但知道循环结束的条件

例:从自然数1开始累加,直到累加和大于1000为止,统计被累加的自然数的个数,并把统计的个数送入n单元,把累加和送入sum单元。

分析:

根据题意,被累加的自然数的个数事先未知,因此不能用计数方法控制循环。但题目中给定一个条件,即累加和大于1000则停止累加,因此,可以根据这一条件控制循环。我们用R3寄存器放累加和,用R4寄存器放每次取得的自然数,其中它的值也是统计自然数的个数。

     AREA  SUM, CODE, READONLY   ; 代码段的名字 SUMENTRY                               ; 程序的入口CODE32
startLDR   R0,   =n            ; 将数据段中自然数的个数n的地址加载到R0寄存器LDR   R1,   =sum       ; 将数据段中自然数的累加和sum的地址加载到R1寄存器LDR   R3,   =0            ; R3存放自然数的累加和LDR   R4,   =0            ; R4用于循环个数的统计/每次取得的自然数LDR   R5,   =1000      ; R5用于循环结束的界限值
continueADD R4,   R4,       #1    ; 取下一个自然数ADD  R3,   R3,      R4    ; 累加自然数CMP R3,   R5             ; 比较累加和是否超过了1000BCC    continue            ; 如果小于1000,那么跳到compare执行STRCS   R3,  [R1]     ; 如果大于1000,那么将累加和存储到R1所指向的单元中STRCS   R4,   [R0]    ; 如果大于1000,那么将已累加的自然数个数值存储; 到R0所指向的单元中 stopMOV    r0, #0x18LDR     r1, =0x20026          SWI     0x123456 AREA  Data, DATA, READWRITE
n   DCD 0       ; 定义累加的自然数的个数
sum DCD 0      ; 定义自然数的累加和END

子程序设计

子程序概念

如果在一个程序中的多处用到同一段程序代码,那么可以把这段共同的程序代码抽取出来,写成一个相对独立的程序段,每当需要执行这段代码时,就调用这个程序段,执行完这个程序段后,再返回原来调用它的程序。这样编写程序时,就不必重复写这段代码了,而这样的程序段称为子程序或子过程。

子程序的调用与返回

主程序中使用BL指令实现子程序的调用

BL 子程序名

在子程序结束处,使用如下指令返回到主程序中。

MOV PC, LR

主程序与子程序之间的参数传递

主程序调用子程序时,可以向子程序传递一些参数;同样,子程序运行后也可把一些结果参数传回给主程序。主程序与子程序之间的这种信息传递称为参数传递。

三种参数传递方式

  1. 寄存器传递参数方式
  2. 存储区域传递参数方式
  3. 堆栈传递参数方式

寄存器传递参数方式

例:用子程序实现内存区里的字符串拷贝功能,即将存储单元中源字符串对应拷贝到目的字符串中。

技术思想:主程序将待传递的数据直接写入约定的通用寄存器,在子程序中直接使用;或子程序返回后,主程序直接从约定的通用寄存器中获得子程序的结果数据。

应用特点:这种方式适合于传递较少参数的应用场合。

解题思路:

通过设定两个地址指针,分别指向存储区中的源字符串和目的字符串;然后通过加载和存储指令(LDR和STR)的寄存器间接寻址方式,依次从源字符串读取一个字符数据,写入到目的字符串的对应字符位置中,直到遇到源字符串的结束标志’\0’为止。

AREA    StrCopy, CODE, READONLYENTRYCODE32
startLDR       R1,    =srcstr        ; R1指向数据区的源字符串LDR       R0,    =dststr        ; R0指向数据区的目的字符串BL          strcopy                 ; 调用子程序strcopy,完成字符串拷贝
stopMOV     R0,     #0x18            ; 程序结束返回编译器调试环境LDR      R1,     =0x20026SWI        0x123456
strcopy LDRB     R2,     [R1],    #1    ; 将R1指向的单元内容加载到R2中STRB      R2,     [R0],    #1    ; 将R2中的数存储到R0指向的单元中CMP       R2,    #0                 ; 检查R0的值是否等于0BNE        strcopy                  ; 如果不等于0,那么转到strcopy处执行 MOV       PC,    LR               ; 子程序返回 AREA    Strings, DATA, READWRITE
srcstr  DCB "First string - source",0     ; 源字符串
dststr  DCB "Second string - destination",0   ; 目的字符串END 

存储区域传递参数方式

例:通过设置的入口参数查找函数地址表,实现选择不同的函数功能。

说明:本题中通过事先将函数地址存放在存储单元中,通过查找地址表的方法,实现根据“选择项(choice)”进入不同的函数体功能。

技术思想:主程序和子程序约定了某一共享内存块用于参数传递,主程序在BL调用子程序前,先将要传递的参数写入到约定的存储单元,子程序可从约定的内存读取这些参数;子程序返回时,也可以使用该方式将数据传给主程序。

应用特点:这种方式可以传递大批量数据。

实现方法:当主程序与子程序有较多的数据需要传递时,可以通过共享内存区或传内存数据块地址方式来传递批量数据。

通过伪指令ADR直接装载近距离数据块地址;

通过伪指令ADRL直接装载中距离数据块地址;

通过语句LDR Rd, =Label转载远距离的数据块地址;

       AREA    Jump, CODE, READONLYnum     EQU     4         ; 函数地址表内容的个数ENTRYCODE32
startLDR   R0,   =choice       ; R0指向存储区的choice单元LDR   R0,   [R0]      ; 设置第一个参数:选择执行哪一个函数MOV  R1,   #16        ; 设置第1个操作数MOV  R2,   #2     ; 设置第2个操作数BL       arithfunc        ; 调用子程序arithfunc
stopMOV   R0,   #0x18       ; 程序结束返回编译器调试环境LDR    R1,   =0x20026SWI         0x123456
arithfuncCMP   R0,    #num                     ; 比较R0的值是否超过函数地址表的个数MOVHS   PC, LR       ; 如果大于,那么就返回到标号stop处ADR   R3,    JumpTable   ; 将函数地址表的地址作为基地址LDR    PC,   [R3, R0, LSL #2]   ; 根据R0参数进入对应的子程序JumpTable   ; 函数地址表的入口基地址DCD        DoAdd       ; 加法子程序DCD  DoSub       ; 减法子程序DCD  DoMul       ; 乘法子程序DCD  DoDiv       ; 除法子程序
DoAddADD   R0,   R1,    R2               ; R0 = R1 + R2MOV   PC,   LR     ; 返回
DoSubSUB    R0, R1,    R2       ; R0 = R1 - R2MOV   PC,    LR      ; 返回
DoMul   MOV   R0,   R1,  LSL R2     ; R0 = R1 << R2MOV   PC,   LR        ; 返回
DoDiv   MOV   R0,   R1,  LSR R2         ; R0 = R1 >> R2MOV   PC,   LR        ; 返回        AREA  NUM, DATA, READWRITE
choice  DCD 3           ; 0:表示选择加法子程序   1:表示选择减法子程序; 2:表示选择乘法子程序   3:表示选择除法子程序END

堆栈传递参数方式

主程序和子程序使用同一个堆栈,主程序在BL调用子程序前,先将要传递的参数压入到堆栈中,子程序可从堆栈中读取传过来的数据;子程序返回需要向主程序传递参数时,也可使用此方法。

参考文献:

孟祥莲.嵌入式系统原理及应用教程(第2版)[M].北京:清华大学出版社,2017.

嵌入式:ARM汇编语言程序设计基础教程相关推荐

  1. 只能输入字母的c语言程序设计教程课后答案,c语言程序设计基础教程_习题答案20120319...

    <c语言程序设计基础教程_习题答案20120319>由会员分享,可在线阅读,更多相关<c语言程序设计基础教程_习题答案20120319(54页珍藏版)>请在技术文库上搜索. 1 ...

  2. java界面编辑教程_java程序设计基础教程第六章图形用户界面编辑.docx

    java程序设计基础教程第六章图形用户界面编辑.docx 还剩 27页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环保! 内容要 ...

  3. 创意c语言程序设计,重庆理工大学-c语言程序设计基础教程_习题答案(纪纲_金艳).doc...

    重庆理工大学-c语言程序设计基础教程_习题答案(纪纲_金艳).doc 还剩 56页未读, 继续阅读 下载文档到电脑,马上远离加班熬夜! 亲,很抱歉,此页已超出免费预览范围啦! 如果喜欢就下载吧,价低环 ...

  4. 《Java Web程序设计基础教程》简介

    本书是关于Java Web开发的基础教程,共分15章.第1章介绍如何构建Java Web应用:第2.3章介绍如何解决Java Web应用的输入和输出问题:第4-6章对登录功能进行了3次重构,这也是Ja ...

  5. c语言程序设计勘误,《程序设计基础教程(C语言)》勘误表

    <<程序设计基础教程(C语言)>勘误表>由会员分享,可在线阅读,更多相关<<程序设计基础教程(C语言)>勘误表(2页珍藏版)>请在人人文库网上搜索. 1 ...

  6. c语言程序设计试题汇编第三版勘误,c语言程序设计基础教程----勘误记录.pdf

    程序设计基础教程--C 语言版 勘误条目: 目录:2.3 节的"标识符"改到 1.7.1 节 第一章 C 语言程序设计基础 第二章 C 语言中的数据类型及其基本操作 P3317: ...

  7. c语言程序设计:现代方法 勘误,C语言程序设计基础教程----勘误记录

    <C语言程序设计基础教程----勘误记录>由会员分享,可在线阅读,更多相关<C语言程序设计基础教程----勘误记录(4页珍藏版)>请在人人文库网上搜索. 1.程序设计基础教程C ...

  8. c语言程序设计基础课后习题答案,2011级C语言程序设计基础教程课后习题答案

    1.C 语言课后习题习题答案详解(11 级教材)第 1 章1.1 填空题1.1.1 应用程序 ONEFUNC.C 中只有一个函数,这个函数的名称是 _main .1.1.2 一个函数由_函数头 _和_ ...

  9. 只能输入字母的c语言程序设计教程课后答案,c语言程序设计基础教程_习题答案解析.doc...

    c语言程序设计基础教程_习题答案解析.doc 习题答案 第1章 填空题 应用程序ONEFUNC.C中只有一个函数,这个函数的名称是__main . 一个函数由__函数头__和__函数体__两部分组成. ...

最新文章

  1. 快讯 | 美国投资公司Avenue Capital Group联合创始人Marc Lasry:比特币价格可能达到40,000美元...
  2. [USACO1.1]贪婪的送礼者Greedy Gift Givers
  3. 不忘每份支持,网易云信感谢一路有你
  4. python标记跳转_Geany的跳转到标记定义“功能如何使用
  5. VTK:模型之ExtractLargestIsosurface
  6. ClassLoader的常用方法及获取方法
  7. 谷歌云请更正这张卡片的信息_如何识别和更正Google Analytics(分析)报告中的(未设置)值
  8. Java中的策略设计模式
  9. qml 连线_将QML信号连接到C 11 lambda插槽(Qt 5)
  10. 【图像隐写】基于matlab GUI DCT数字水印嵌入与提取【含Matlab源码 943期】
  11. java 4.0 下载_javax.servlet-api-4.0.1.jar包下载
  12. 百度安全实验室提醒您:连接千万条,安全第一条;加密不认证,亲人两行泪。...
  13. Excel在两列排序不同的数据中查找出不同的数据
  14. 新睿云 亚马逊_一窥新发现的亚马逊欺诈检测器
  15. 好用的企业邮箱有哪些?
  16. bps和pps各自是什么意思?
  17. cassandra java cql_使用Cassandra CQL Java Driver 访问Lindorm
  18. Linux下用命令行彻底删除文件
  19. 前端CSS核心内容浮动
  20. [UOJ198]时空旅行

热门文章

  1. linux虚拟网口不同vlan,管理交换机虚拟局域网VLAN的4种划分
  2. php-新特性之match解析
  3. 英语计算机答题卡模板,英语答题卡模板.doc
  4. RapidMiner 离散/缺失
  5. Android 进阶第一篇——善用工具
  6. 讯飞语音输入法解包即用,绿色便携免安装版
  7. Altova xmlSpy测试webService的使用
  8. Android 发布Google Play 应用市场(2021.10.18)
  9. ADB和Fastboot最新版的谷歌官方下载链接
  10. 《机器学习实战》第12章*