【ARM汇编】分支结构如何实现?

在这里插入图片描述

CSDN话题挑战赛第1期
活动详情地址话题PK赛
参赛话题:汇编知识分享
话题描述:我们的计算机知识就像一座金字塔,底层是数学,上面是数字电路,然后是汇编,再往上是操作系统、网络、数据库、高级编程语言、框架等等…我们不可能精通这个金子塔的每一层, 但是想走的更远就必须要了解这个金字塔的底层。因此,学习汇编并不是为了用汇编在应用层设计程序,而是为了深刻理解机器运行程序的机理。就像对于人来说不能没有常识一样,尽管常识不能直接挣钱吃饭,但它影响谈吐,影响你的判断力和决断力,决定着你接受新事物和新知识的程度。汇编就是计算机语言里面的常识和基础。

大家好,我是汤姆凯特。

在这里插入图片描述

每篇前言

☀️作者简介:大家好我是汤姆凯特,大家可以叫我汤姆
🐋个人主页:IM汤姆凯特的CSDN博客
🎁系列专栏:【ARM嵌入式基础】


汇编中分支结构如何实现?

高级语言中用if-else语句和switch语句就可以很方便的实现不同情况的语句分支,那汇编中应该用什么办法来实现这一功能?其实在前面写的文章中需要判断数组中的正负数然后求和,就用到了简单的分支结构,这次来详细介绍一下。

示例:

举一个最简单的分支判断语句

从键盘上输入一个 32 位有符号整数,赋给字变量 sinteger;请按照下面的要求输出:

图解:

在这里插入图片描述

伪代码

if (sinteger == 0)        
    输出:sign = 0; 
else  if ( siteger > 0)    
    输出: sign = 1;       
else         
    输出: sign =1; 

汇编语言如何实现

汇编中实现分支语句其实用到的就是指令CMP、指令B和各种判断后缀

另外,汇编实现分支结构时有个规律:在N分支结构中,至少要使用N-1条无条件转移指令。它的作用与C语言中switch语句功能相同,就是转移到在N分支结构中的公共出口处。

第一步、构建数据输入

在这个示例中明显是需要输入一个数据,并且需要把数据存到sinteger中。

1.全局变量定义

输入输出的格式串

sinteger分配内存空间

.data 
  fmt:.asciz "%d"   
  fmt1:.asciz " sign=%d\n"      
  sinteger:.word  0 

2.调用scanf键入数据

将scanf的值存到sinteger中

从sinteger中取出以便分支判断使用

    ldr r0,=fmt    
    ldr r1,=sinteger    
    bl  scanf     
    ldr r1,=sinteger
    ldr r1,[r1]

第二步、建立分支结构

汇编中分支判断,只需要CMP一次,对不同的情况做出不同的选择即可

在比较完之后一定要有跳转出口,如果没有跳转只有指令加判断后缀也能实现,但是当分支语句中要实现的功能比较复杂时,就不能用这种方式了。

1.分支结构中只有一条语句

这种实现起来比较简单,只需要在CMP后加不同的指令后缀执行动作就行了,例如在这道题中可以这样简单的实现功能。

cmp r1,#0 
    moveq  r1,#0    
    movlt  r1,#-1
    movgt  r1,#1 

2.完整的分支结构

这就需要用到分支跳转B(后缀加跳转条件)

 cmp r1,#0   
    bne    L1   //  if r1!=0 goto L1 
    mov r1,#0  
    b    exit 
L1: 
    blt    L2    //  if r1<0 goto L2        
    mov  r1,#1        
    b    exit 
L2: 
    mov r1,#-1  // r1<0 

汇编源码

代码后面都加上了语句的注释

// 符号函数  
.data 
  fmt:.asciz "%d"   
  fmt1:.asciz " sign=%d\n"      
  sinteger:.word  0 
.text 
.globl main  
 main:  
    push {lr}                // push return address onto stack 
    ldr r0,=fmt    
    ldr r1,=sinteger    
    bl  scanf     
    ldr r1,=sinteger
    ldr r1,[r1] 
    cmp r1,#0     // 生成条件码! 
    bne    L1   //  if r1!=0 goto L1        
    mov  r1,#0        
    b    exit 
L1: 
    blt    L2    //  if r1<0 goto L2        
    mov  r1,#1        
    b    exit 
L2: 
    mov r1,#-1  // r1<0 
exit: 
    ldr r0,=fmt1       
    bl  printf         
    mov r0, #0            // move return code into r0      
    pop  {lr}             // pop return address from stack      
    mov pc, lr            // end of main,return to Linux  
.end                       // end of assembler 

运行调试

在这里插入图片描述


总结

  • 汇编中的分支语句用CMP指令、B跳转指令以及各种判断后缀组成。

  • 写分支判断时一般情况是先做出判断,当满足条件指令时进行跳转,如果不满足按照顺序执行。

  • 如果分支语句的执行框中只有比较简单的指令,可以直接用一条CMP+多条判断执行即可,简化了分支的建立。


本期内容就结束了,如果内容有误,麻烦大家评论区指出!
如有疑问可以在评论区留言!
下期预告: 用汇编输出数组中最大值最小值

CSDN话题挑战赛第1期
活动详情地址话题PK赛

  • 46
    点赞
  • 42
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 39
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 39
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

IM汤姆凯特

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值