一文搞懂 ARM 64 系列: ADD(立即数版)

汇编中,加法指令很重要,因为它是执行其他很多指令的基础。

同时,加法指令也会影响NZCV标志。有关NZCV的介绍,可以参看《一文搞懂 ARM 64 系列: ADC》。

ARM64汇编中,ADD指令有3种形式,这里介绍第一种形式,也就是与立即数相加。

1 指令语法

cpp 复制代码
ADD <Xd|SP>, <Xn|Sp>, #imm{, shift}

{}里的内容表示是可选的。

shift表示LSL(逻辑左移)的位数,有2个取值,一个是0,一个是120是其默认值。

所谓LSL(逻辑左移),是指将数值整体向左移动,低位补0。如果高位被移出去,直接丢弃。

2 指令语义

整个指令就是将源寄存器<Xn|SP>,与立即数imm(如果有必要,需要进行LSL)相加,将结果写入目的寄存器<Xd|SP>

注意 ,这条指令不影响NZCV标志。

cpp 复制代码
(<Xd|SP>, _) = <Xn|Sp> + imm << shift

3 NZCV 如何受影响

虽然这条指令最终不影响NZCV标志,但是搞清楚NZCV如何受影响,还是很有必要的。

1 将源寄存器的值<Xn|SP>imm << shift都当成无符号整型数,两数相加,得到一个无符号整型数的结果,记作u_result。此时计算时不考虑溢出:

cpp 复制代码
<Xn|SP> = 0xffffffffffffffff // 64 bit 全 1
(imm << shift) = 1
u_result = 0xffffffffffffffff + 1 = 0x10000000000000000 // 2^64,而不是 0

2将源寄存器的值<Xn|SP>imm << shift都当成有符号整型数,两数相加,得到一个有符号整型数的结果,记作s_result。此时计算时不考虑溢出:

<Xn|SP> = 0xffffffffffffffff // 64 bit 全 1,此时当成 -1 看待
(imm << shift) = 0x8000000000000000 // 64 bit 最小负整数 -9223372036854775808
s_result = -1 + (-9223372036854775808) = -9223372036854775809 // 而不是 0x7fffffffffffffff

3u_result中取(63~0)64bit,记作result;

4 如果result的最高位是1,那么N = 1;

5 如果result = 0,那么Z = 1;

6 如果把result当成无符号整型数,它的值等于u_result,那么C = 0;如果不等于,那么C = 1,也就是在进行加法运算时,发生了进位。

7 如果把result当成有符号整型数,它的值等于s_result,那么V = 0;如果不等于,那么V = 1,也就是说在进行加法运算,发生了溢出。

相关推荐
顾建安10 天前
使用aarch64-unknown-linux-musl编译生成静态ARM64可执行文件
rust·交叉编译·arm64·静态编译
aspirestro三水哥1 个月前
4.4.5 timer中断流向Linux(从interrupt log回放)
linux·运维·服务器·arm64·xenomai
chaoguo12341 个月前
一文搞懂 ARM 64 系列: PACISB
arm64·pacibsp
CYRUS STUDIO1 个月前
ARM64汇编寻址、汇编指令、指令编码方式
android·汇编·arm开发·arm·arm64
CYRUS STUDIO2 个月前
详解ARM64可执行程序的生成过程
android·c语言·汇编·c++·gdb·arm64
鹏大师运维3 个月前
Mac M芯片上安装统信UOS 1070arm64虚拟机
linux·macos·信创·国产化·arm64·统信·uos1070
橘色的喵6 个月前
针对ARM64嵌入式系统的Linux内核参数优化
性能优化·linux内核·嵌入式·arm·内存管理·arm64·网络优化
chaoguo12346 个月前
一文搞懂 ARM 64 系列: 一文搞懂 ARM 64 系列: 函数调用传参与返回值
arm64·参数传递·返回值
chaoguo12347 个月前
一文搞懂 ARM 64 系列: 寄存器
arm·arm64·寄存器