ARM64汇编04 - 条件码

这篇具有很好参考价值的文章主要介绍了ARM64汇编04 - 条件码。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

关于分支控制与条件码的作用可以去看 《CSAPP》的第 3.6 节,讲的非常清楚,建议看看,这里就不重复了。

我们直接使用一个例子来简单理解汇编是如何实现分支控制的:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main()
{
    time_t t;
    srand((unsigned) time(&t));

    int a = rand();
    int b = rand();

    printf("a = %d, b = %d\n", a, b);

    if (a > b)
    {
        printf("a win!!!\n");
    }
    else if (a < b)
    {
        printf("b win!!!\n");
    }
    else
    {
        printf("both win!!!\n");
    }

    return 0;
}

编译后,使用 ida 打开,查看其核心逻辑:

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

1处的 w19 与 w20 储存着 a 与 b 的值,CMP 会对这两个值做比较。

CSEL 指令介绍:

CSEL <Xd>, <Xn>, <Xm>, <cond>

cond 是有一个表可以查的,我们后面会说。这个指令的意思是,如果 cond == true,Xd = Xn,否则 Xd = Xm。

2 处的 CSEL 指令的意思是如果 LT 的值是 true,那么 x8 = x9,否则 x8 = x8。x9 的值是 b win。结合源代码,可以猜测出  CMP 就是做了一个减法操作。

综合一下,当 w19 < w20,那么输出 x9(b win),否则输出 x8(both win)。

3 处的分析与 2 一样就不展开了,当 w19 > w20,那么输出 x0(a win)

通常,在有分支的位置,会出现 CMP 等指令,它会修改 ZNCV 这些 flags 的值,然后后面会跟一些需要根据 flags 值来决定分支走向的汇编代码,比如 CSEL。

我们编写的程序,肯定是有很多分支的。所以,cond 非常的重要。

Condition code

arm64 的条件码如下,与 arm32 有点区别,但是不大:

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

我们在上面的例子中看到的 LTGT 这里都是有对应的。

LT 表示有符号的小于,GT 表示有符号的大于。

LT 需要检查 N 与 V 的值,GT 需要检查 Z,N,V的值。

关于 ZCNV 这几个标志位的解释,不太好描述,先简单理解:

  • N:当操作结果为负数时,设置为1,否则为0。

  • Z:当操作结果为0时,设置为1,否则为0。

  • C:当操作结果发生进位或者减法结果无借位时,设置为1,否则设置为0。

  • V:当操作导致溢出时,设置为1,否则设置为0。

实际上,会有相当多的指令会更新这些 flag 的值,比如,一些运算指令等。但是运算指令想要更新 flag,还需要加 S 后缀。比如,ADDS指令。

有符号与无符号

从上面的条件码表中可知:

  • 有符号的大于为:GT(Greater than)

  • 有符号的小于为:LT(Less than)

  • 无符号的大于为:HI(higher)

  • 无符号的小于等于为:LS(lower or same)

由于助记符设计的有符号的小于使用的单词是 Less,无符号的小于采用的 lower,导致它们看起来会比较像。

在汇编中出现了 LT 与 LS 后缀,很难会一下子反应过来,这到底是有符号还是无符号。

x86 中的有符号与无符号区分的比较开,有符号使用greater/less,无符号使用 above/below。

LS后缀

由于 cond 后缀有一个 LS,表示 less or same。而 B 指令也可以接 cond 后缀,所以会出现 BLS 指令。

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

这很好理解,但是对初学者来说,有一个麻烦的地方,就是还有一个 BL 指令,我们还记得有些指令是可以加 S 后缀的。

所以当我们看到  BLS 指令的时候,它到底表示的是 B + LS ,还是 BL + S 呢?

如果你翻arm手册,就知道,BL 是没有 S 后缀的,也就是说它不设置 flag:

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

C标志位的奇怪表现

使用 ida 来简单观察一下C flag 的变化情况。

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

测试加法,0 + 1,单步后,查看 C 位变化:

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

发现 C 位无变化,很正常。

再测试一个减法,2 - 1

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

单步后,查看 C 位变化:

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

发现,C 位居然变成了 1,这个表现就与x86中是相反的,设计的很奇怪。

再测试一个 1 -2

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

单步后,查看 C 位变化:

ARM64汇编04 - 条件码,ARM64汇编,前端,java,算法,汇编

C 位无变化,N位变成了 1,因为结果是 -1。

对于C位,需要注意到,在减法中,它与 x86 中的表现是相反的,与直觉也是相反的。文章来源地址https://www.toymoban.com/news/detail-838649.html

到了这里,关于ARM64汇编04 - 条件码的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【ARM64 常见汇编指令学习 13 -- ARM 汇编 ORG 伪指令学习】

    上篇文章:ARM64 常见汇编指令学习 12 – ARM 汇编函数 的学习 下篇文章:ARM64 常见汇编指令学习 14 – ARM 汇编 .balign,.balignw,.balign 伪指令学习 在ARM汇编中,\\\" org \\\"是一个汇编器伪指令,用于设置下一条指令的装入地址。\\\" org \\\"后面跟着的是一个表达式,这个表达式的值就是下一条

    2024年02月14日
    浏览(34)
  • 汇编基础(2) -- ARM64

    ARM架构中,ARM64(也称为AArch64)是一种64位处理器架构,它是ARMv8指令集的一部分。与之前的32位ARM架构相比,ARM64提供了更大的寄存器容量、更广阔的地址空间和更高的计算能力。 64位版本的指令集和32位版本的指令集有一些区别,这些区别主要涉及到以下几个方面: 寄存器

    2024年02月07日
    浏览(25)
  • ARM64汇编基础

    到目前为止,大部分的移动设备都是64位的arm架构,一直想抽个时间系统学习下,这个周末就专门来学习下。毕竟两天的时间,也只是简单的入门了解下,为后续工作和学习打下基础。 本次学习的主要内容包括寄存器、指令系统以及堆栈函数相关的知识,了解这些知识后,后

    2024年02月07日
    浏览(28)
  • 【ARM 常见汇编指令学习 5 -- arm64汇编指令 wzr 和 xzr】

    上篇文章:ARM 常见汇编指令学习 4 – ARM64 比较指令 cbnz 与 b.ne 区别 下篇文章:ARM 常见汇编指令学习 6 - bic(位清除), orr(位或), eor(异或) ARMv8 在硬件层名引入了一个新的 zero 寄存器 : XZR (64-bits), WZR (32-bits)。比如要将某一变量赋值为0x0, 由于ARM不允许直接操作内存单元上的数据

    2024年02月15日
    浏览(43)
  • 【ARM64 常见汇编指令学习 14 -- ARM 汇编 .balign,.balignw,.balign 伪指令学习】

    上篇文章:ARM64 常见汇编指令学习 13 – ARM 汇编 ORG 伪指令学习 下篇文章:ARM64 常见汇编指令学习 15 – ARM 标志位的学习 .balignl 是一个伪操作符,伪操作符的意思就是机器码里,并没有一个汇编指令与其对应,是编译器来实现其功能的。. balignl 是 .balign 的变体。 .balignl 完整

    2024年02月14日
    浏览(31)
  • ARM64 寄存器、常用汇编指令收集

    ARM64 有34个寄存器,包括31个通用寄存器、SP、PC、CPSR。 寄存器 位数 描述 x0-x30 64bit 通用寄存器,如果有需要可以当做32bit使用:WO-W30 FP(x29) 64bit 保存栈帧地址(栈底指针) LR(x30) 64bit 通常称X30为程序链接寄存器,保存子程序结束后需要执行的下一条指令 SP 64bit 保存栈指针,使用

    2023年04月20日
    浏览(32)
  • 【ARM64 常见汇编指令学习 21 -- ARM RET 与 ERET】

    请阅读 【嵌入式开发学习必备专栏 】 在 ARMv8 架构中, RET 指令用于从函数或者过程返回。它主要负责从当前过程跳转回调用者,并恢复调用者的程序计数器 (PC) 的值。 语法: Xn 是一个可选的寄存器,通常为 X30 (也称为 LR ,链接寄存器),其中包含返回地址。如果没有指

    2024年04月10日
    浏览(73)
  • [ARM 汇编]进阶篇—控制流指令—2.2.1 条件分支指令

    在 ARM 汇编中,条件分支指令用于根据特定条件改变程序的执行流程。在本节中,我们将详细介绍 ARM 汇编中的条件分支指令,并通过实例帮助你更好地理解和掌握这些指令。 在ARM汇编语言中,条件分支(Conditional Branch)指令用于在满足某个条件时执行跳转操作。ARM汇编中有

    2024年02月03日
    浏览(31)
  • 【ARM64 常见汇编指令学习 20 -- ARM 指令 .include与 .asciz 详细介绍】

    在 ARM 汇编语言中, .include 命令用于插入另一个源文件的内容。它的作用类似于 C 语言中的 #include 预处理命令。这个命令通常在源文件的顶部使用,但也可以在任何地方使用。 语法如下: 这里的 \\\"filename\\\" 是你想要包含的文件名。这个文件名可以是绝对路径,也可以是相对于

    2024年02月11日
    浏览(40)
  • 用ARM进行汇编语言编程(4)带有分支的循环和条件指令执行

    ARM 编程模拟器网站地址: 在arm里也有和高级语言一样的for和while循环,可以根据条件来判断是否执行 首先我们创建一个data标签,然后在里面写一个分支,存放一些数值,然后使这些存放的数值依次相加 然后我们要将list加载到内存里 然后使用直接寻址,将r0寄存器里的值放

    2024年02月06日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包