程序集分支/循环和函数如何工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了程序集分支/循环和函数如何工作相关的知识,希望对你有一定的参考价值。

刚刚在课堂上上了第一堂课。讲师没有解释太多,因为我们必须使用书籍来阅读装配的工作原理。我的编程背景是Python和C ++,并且即使考虑在代码中来回跳转也会感到亵渎。

在谈论分支时,问题一直困扰着我,似乎在我的书中没有任何地方可以解释。基本上OP代码B +(EQ,PL等)根据条件和标志进行分支。例如,“BEQ位置”将分支到“位置”,如果....即,如果是什么。从我能够做出的,它使用先前的设置来找出条件(在这种情况下,如果某些东西是相等的(Z = 1))。如果BEQ看到前一个指令的回归以评估EQ,那么我怎样才能做出一个循环,其中第一个R0(寄存器0)得到值0,然后发生其他事情,最后我做了一下检查R0是否为零的条件分支?

问题2:我还注意到,如果你正在做某种功能:

WhileLoop:
     MOV R0, R1
     ..bla bla bla
     BEQ WhileLoop

我怎么知道BEQ回归“WhileLoop”?这是否意味着对于我所做的每一项功能我都需要称它为不同的东西。也许我不正确理解功能。

请帮忙。

答案

您需要阅读ARM文档。你的问题的答案就在那里。

是的ARM使用标志。与使用标志的任何指令集一样,您需要检查您正在使用或希望使用的每条指令,或者用于一般性理解,以查看它们修改的标志是什么。例如,AND操作是否有意义设置进位标志?不,但是设置零标志是否有意义?当然它可能有用,或者有时它们TST设置零标志但AND不依赖于架构。

与典型的flag basd解决方案不同,ARM有一段时间的扭曲,你必须要求ASK指令来设置标志。如果你注意到了

loop:
  sub r0,#1
  bne loop

没有做你想做的事,因为写的(根据arm文档)减法dos​​不会触摸任何标志,特别是我们正在测试的Z标志,但......

loop:
  subs r0,#1
  bne loop

这段代码,减去DOES触摸Z标志。

它允许像这样的东西

  cmp r2,r3
  moveq r1,#1
  bxeq lr
  mov r1,#0
  bx lr

或者说

  if(foo==1)
  {
     bar++;
  }

你通常需要实现它

compare with 1
branch if not equal to skip
increment
skip:

所以你有一个管道,也许用分支获取命中

但反而

compare with 1
increment if equal

条件执行,条件位。

现在,对于全尺寸的手臂指令,拇指说明是一个不同的故事。

使用64位指令集aarch64,这整个有条件的东西都消失了,每个条件执行指令烧掉四个位有点痛苦,不够用。他们可能有32个通用寄存器,而这可能更有用......

所以不确定你对函数的要求,首先用汇编语言,你经常可以使用像WhileLoop这样的标签。汇编程序将其转换为正确的指令,WhileLoop不是指令,它基本上是一个地址,在这种情况下,汇编程序应该使用您要求的指令并执行pc相对偏移(不使用固定地址,它会如何计算标签和beq之间的许多指令,并说如果等分支向后N指令)。如果你将beq放到某个标签上并且在另一个模块/对象中定义了,那么链接器将不得不稍后修补该指令。

至于函数,所以如果用C语言编写程序并且我想制作几个指令,我是否需要使所有函数名称不同?是的。在组装中确实没有函数这样的东西,有一些指令可以给出一个错觉,但它只是一个花哨的标签。但是代表一个函数的代码,如果你想编写其中的7个是的,你需要为每个函数使用不同的标签。汇编语言与它无关。

gnu汇编程序有一个有趣的功能,没有理由假设其他汇编语言支持(汇编语言由汇编程序,工具,而不是目标(ARM指令集)定义),非常容易为许多不同的指令集演示,易于编写的臂组件不能组装在所有主动支持的组装器上。所以这是一个gnu汇编程序技巧,可能会或可能不会帮助你标签

1:
 subs r0,#1
 beq 1f
 b 1b
1:

你通常会想要做bne但这证明了这个功能。一个数字的标签是特殊的1f表示标签1:转发所以下一个标签1:向下翻页。 1b表示1:向后所以从那一点向后读取页面以找到下一个1:所以你不必这样做

myfunction:
...
myfunction00:
...
myfunction01:
...
myfunction02:
...

因为你正在努力制作中间标签来处理东西和循环上的简单分支。

您可以选择是特征还是负担,因为它会创建一种习惯,可能是也可能不是特定于工具的。

以上是关于程序集分支/循环和函数如何工作的主要内容,如果未能解决你的问题,请参考以下文章

如何使用引导程序和 for 循环在 django 中创建电影片段?

Android.mk 函数进阶教程 - 分支循环子程序

C语言错题集2:分支与循环

如何使用事件侦听器来加载动画片段的循环

使用从循环内的代码片段中提取的函数避免代码冗余/计算开销

3.1运算符+代码结构(分支+循环)+函数