ARM64体系结构编程3-算数和移位指令

article/2025/10/7 8:05:17

条件操作码

条件标志位描述
N负数标志(上一次运算结果为负值)
Z零结果标志(上一次运算结果为零)
C进位标志(上一次运算结果发生了无符号溢出
V溢出标志(上一次运算结果发生了有符号溢出

加法指令

add x0, x1, #1	//把x1寄存器的值加过加上立即数 1,结果写进x0寄存器中
add x0, x1, #1, LSL 12	//把立即数 1 算数左移 12 位,然后再加 x1 寄存器的值,结果写入 x0 寄存器中

注意:立即数是一个无符号的,取值范围为 0~4095

add x0, x1, x2    //x0=x1+x2
add x0, x1,x2, LSL 2	//x0=x1+(x2 << 2)mov x1, #1
mov x2, #0x8a
add x0, x1, x2, UXTB
//运行结果是 0x8B,UXTB 对寄存器 x2 进行无符号扩展,结果为0x8a,再加上 X1 寄存器的值,x0最终结果为0x8b
add x0, x1, x2, SXTB	
// SXTB 对 x2 寄存器的值低8位进行有符号扩展,结果为0xFFFFFFFFFFFFFF8A,然后再加上 X1 寄存器的值,x0最终结果为0xFFFFFFFFFFFFFF8B

移位操作的加法指令

add x0, x1, x2, LSl, 3	//x0=x1+(x2<<3))

注意,移位的取值范围 0~63

  • ADDS 指令

adds 指令是 add 指令的变种,它们的区别是指令执行结果会影响 PSTATE 寄存器的 N、Z、C、V 标志位,例如当计算结果发生无符号数溢出时,C=1 。

mov x1, 0xffffffffffffffff
adds x0, x1, #2
mrs x2, nxcv

x1 的值(0xffffffffffffffff)加上立即数 2 一定会触发无符号溢出,最终 X0 寄存器的值为 1,同时还设置 PSTATE 寄存器的 C 标志位为 1,我们可以通过读取 NZCV 寄存器来判断,最终 X2 寄存器的值为 0x20000000 ,说明第 29 位的 C (进位标志)字段置 1,

  • ADC xd,xn, xm //Xd寄存器的值等于 Xn 寄存器的值加上 Xm 寄存器的值加上 C ,C表示 PSTATE 寄存器的 C 标志位。
mov x1, oxffffffffffffffff
mov x2, #2adc x0, x1, x2
mrs x3, nzcv

ADC 指令计算过程: 0xFFFFFFFFFFFFFFFF + 2 + C ,因为 0xFFFFFFFFFFFFFFFF + 2 的过程中已经出发了无符号溢出,C=1 ,所以最终计算 X0 寄存器的值为 2,如果读取 NZCV 寄存器,发现 C 标志位也被置为 1 了。

SUB 指令

减法指令

sub x0, x1, #1	//把 x1 寄存器的值减去立即数 1,结果写入 x0 寄存器
//把立即数1算数左移12位,然后把x1寄存器中的值减去(1<<12),把结果写入 x0 寄存器中
sub x0, x1, #1, LSL 12	
1 mov x1, #1
2 mov x2, #0x108a
3 sub x0, x1, x2, UXTB
4 sub x0, x1, x2, SXTB

UXTB 对 x2 寄存器的低 8 位数据进行无符号扩展,结果为 0x8a , 然后再计算 1-0x8a 的值,最终结果为 0xffffffffffffff77

SXTB 对 x2 寄存器的低 8 位数据进行有符号扩展,结果为 0xffffffffffffff8a,然后再计算 1-0xffffffffffffff8a ,最终结果为 0x77 。

sub x0, x1, x2, LSL, 3  //x0 = x1 0 (x2 << 3)

SUBS 指令

减法指令,但是会影响 PSTATE 寄存器的 N、Z、C、V 标志

该指令的计算过程: operand1 + NOT(operand2) + 1 // NOT 表示按位取反

mov x1, 0x3
mov x2, 0x1
subs x0, x1, x2
mrs x3, nzcv	//读取 nzcv 寄存器的值——0x200000000

x2 的值为 0x1,按位取反后的值为 0xfffffffffffffffe , 3 + 0xfffffffffffffffe + 1 , 这个过程会发生无符号溢出,因此 4 个标志位中的 C=1,最终计算结果为 2 。

SBC 指令

进位减法指令,也就是最终计算结果需要考虑 PSTATE 寄存器的 C 标志位

该指令的计算过程;Xd = Xn + NOT(Xm) + C

mov x1, #3
mov x2, #1
sbc x0, x1, x2
mrs x3, nzcv

3 + not(1) + C , 1 按位取反为 0xfffffffffffffffe , 3 + 0xfffffffffffffffe 过程会发生溢出,所以 C=1,再嘉善标志位 C,结果为 2.

比较大小指令 CMP

CMP 指令用来比较两个数的大小,在 A64 中,CMP 指令内部调用 SUBS 指令来实现

cmp x1, x2		// x1 + not(x2) + 1
// 跳转到 label 处
b.cs label		//CS 表示发生了无符号溢出,即 C 标志位置位,CC 表示 C 标志位没有置位
my_test:mov x1, #3mov x2, #2
1:cmp x1, x2b.cs lbret

b 指令的操作由后缀 cs 决定,cs 表示判断是否发生无符号溢出,3 + not(2) + 1 , not(2) = 0xfffffffffffffffd , 3 + 0xfffffffffffffffd + 1 = 1, ,这个过程发生了溢出,C 标志位置为 1, 所以 b.cs 的判断条件成立,跳转到标签 1 处,继续执行。

  • 比较 x1 和 x2 的寄存器的值大小
my_test:mov x1, #3mov x2, #2
1:cmp x1, x2b.ls, 1bret

在比较 x1 和 x2 寄存器的值大小时,判断条件为 LS,表示无符号小于或者等于,那么,在这个比较过程中,我们就不需要判断 C 标志位了,直接判断 x1 寄存器的值是否 小于或等于 x2 寄存器的值即可。因此这里不会跳转到标签 1 处。

以条件标志位示例 array_index_mask_nospec

内核中 array_index_mask_nospec 函数用来实现一个掩码

  • when i n d e x ≥ s i z e index \geq size indexsize, return 0
  • when i n d e x < s i z e index < size index<size, return 掩码 0xFFFFFFFFFFFFFFFF
  static inline unsigned long array_index_mask_nospec(unsigned long idx, unsigned long sz) {unsigned long mask;asm volatile("   cmp %1, %2\n""   sbc %0, xzr, xzr\n": "=r" (mask): "r" (idx), "Ir" (sz): "cc");csdb();return mask;}

上述内嵌汇编转成纯汇编代码

cmp x0, x1
sbc x0, xzr, xzr

x0 寄存器的值 idx,x1 寄存器的值 sz,当 l d x < s z ldx < sz ldx<sz 时,cmp 指令没有产生无符号数溢出,C 标志位为 0,当 i d x ≥ s z idx \geq sz idxsz cmp 指令产生了无符号溢出(其实内置是使用了 subs 指令来实现),C 标志位会置 1。

根据 SBC 指令的计算: 0 + NOT(0) + C = 0-1+C

  • 当 index 小于 size 时,C = 0, 最终计算结果为 -1,也就是 0xFFFFFFFFFFFFFFFF 。

  • 当 index 大于或等于 size 时,C = 1, 最终计算结果为 0.

移位指令

  • LSL:逻辑左移指令,最高位会被丢弃,最低位补 0。
  • LSR:逻辑右移指令,最高位补 0,最低位会被丢弃
  • ASR:算术右移指令,最低位会被丢弃,最高位会按照符号进行扩展。
  • AOR:循环右移指令,最低位会移动到最高位

A64 指令集里没有单独设置算术左移的指令,因为 LSL 指令会把最高位舍弃了

ldr w1, =0x8000008a
asr w2, w1, 1
lsr w3, w1, 1
  • ASR 是算术右移指令,把 0x8000008A 右移一位并且对最高位进行有符号扩展,最后结果为 0xC0000045
  • LSR 是逻辑右移指令,把 0x8000008A 右移一位并且在最高位补 0,最后结果为 0x40000045 。

位操作指令

与操作指令 AND

AND:按位 与 操作

ANDS:带条件标志位的 与 操作,影响 Z 标志位。

mov x1, #0x3
mov x2, #0ands x3, x1, x2   // 0x3 和 0 做 “与” 操作
mrs x0, nzcv		//与 的结果为 0,读取 NZCV 寄存器,可以看到 Z 标志位了

或操作指令 ORR

ORR Xd|SP, Xn, #imm
ORR Xd, Xn, shift #amount
  • 立即数方式:对 Xn 寄存器的值与立即数 imm 进行 或 操作
  • 寄存器方式:先对 Xm 寄存器的值做 移位 操作,然后再与 Xn 寄存器的值进行 或 操作
EOR Xd|SP, Xn, #imm
EOR Xd, Xn, Xm, shift #amount 
  • 立即数方式:对 Xn 寄存器的值与立即数 imm 进行 异或 操作
  • 寄存器方式:先对 Xm 寄存器的值做 移位 操作,然后再与 Xn 寄存器的值进行 异或 操作

位段指令

位段插入 BFI

BFI Xd, Xn, #lsb, #width

BFI 指令的作用是用寄存器 Xn 寄存器中的 Bit[0, width-1] 替换 Xd 寄存器中的 Bit[lsb, lsb+width-1] 替换 Xd 寄存器中的 Bit[lsb, lsb + width-1] , Xd 寄存器中的其他位不变。

val &=~ (oxf << 4)	//val 表示寄存器 A 的值
val |= ( (u64)0x5 << 4)mov x0, #0		//寄存器 A 的值初始化为 0
mov x1, #0x5	bfi x0, x1, #4, #4	//往寄存器A的Bit[7,4}字段设置 0x5

BFI 指令把 X1 寄存器中的 Bit[3,0] 设置为 X0 寄存器中的 Bit[7,4], X0 寄存器中的 Bit[7,4] ,X0 寄存器的值是 0x50。

在这里插入图片描述

位段提取操作指令 UBFIX

UFBX  Xd, Xn, #lsb, #width

UBFX 作用是提取 Xn 寄存器的 Bit[lsb, lsb+width-1], 然后存储到 Xd 寄存器中。另外 SBFX 和 UBFX 的区别只是SBFX 会进行符号扩展,例如 Bit[lsb, lsb+width-1] 为 1,那么写到 Xd 寄存器之后,所有的高位都必须为 1,。

mov x2, #0x8a
ubfx x0, x2, #4, #4
sbfx x1, x2, #4, #4

在这里插入图片描述

SBFX 指令在提取字段之后需要做符号扩展,当提取后的字段中最高位为 1 时,Xd 寄存器的最高位都要填充 1。当提取后的字段中最高位为 0 时,Xd 寄存器里最高位都要填充 0,最终,X1 寄存器的值为 0xFFFFFFFFFFFFFF8 。

在这里插入图片描述


http://chatgpt.dhexx.cn/article/KrVO2Wx5.shtml

相关文章

逻辑、移位操作与空指令的实现

逻辑、移位操作和空指令的实现 1. 流水线数据相关的问题 流水线上经常会有一些被称为“相关”的情况发生&#xff0c;它使得指令序列中下一条指令无法按照设计的时钟周期执行&#xff0c;这些“相关”会降低流水线的性能。 1.1 流水线相关 流水线中的相关可分为&#xff1a…

汇编移位指令SHR,SAR,SAL/SHL,ROR,ROL,RCR,RCL

目录 逻辑右移SHR 算数右移SAR&#xff08;重点&#xff09; 算数/逻辑左移SAL/SHL(完成的操作都一样) 循环右移ROR 循环左移ROL 带进位循环右移RCR 带进位循环左移RCL 总结 例题 一 二 移位指令为双操作数指令&#xff0c;用于将目的的操作数中的二进制数移位。 目…

位移指令实现乘法、除法计算

前言 大家都知道51单片机是有乘法、除法指令的&#xff0c;不管是用C语言还是汇编语言&#xff0c;都是可以直接计算乘法、除法的&#xff0c;我以为&#xff0c;-&#xff0c;*&#xff0c;/ 这些算术运算是单片机的标配&#xff0c;而我公司使用的应广单片机居然没有乘法、除…

微机原理——移位指令

例题 思路 选择移位语句&#xff0c;右移&#xff0c;将AL移出的送入DX左端&#xff0c;将BL移出的送入DX左端。循环八次 MOV AL,01100101B; MOV BL,11011010B; XOR DX,DX;两个值相同&#xff0c;异或结果为0。等效&#xff1a;MOV DX,0 MOV CX,8;count L1: SHR AL,1;逻辑右…

汇编语言---移位指令

移位指令是一组经常使用的指令,包括:算数移位、逻辑移位、双精度移位、循环移位、带进位的循环移位; 移位指令都有一个指定需要移动的二进制位数的操作数,该操作数可以是立即数,也可以是CL的值;在8086中,该操作数只能是1,但是在其后的CPU中,该立即数可以是定义域[1,31]之内的数…

汇编语言——移位指令

基本概念 移位操作指令&#xff1a;移位操作指令是一组经常使用的指令&#xff0c;属于汇编语言逻辑指令中的一部分&#xff0c;它包括移位指令&#xff08;含算术移位指令、逻辑移位指令&#xff09;&#xff0c;循环移位指令&#xff08;含带进位的循环移位指令&#xff09;&…

汇编指令之移位指令

移位指令包括了 算术移位指令、逻辑移位指令、循环移位指令。 格式为:xxx oper1,CL/1 ;移位次数只能是1或者存放在CL里面。 一、算术移位指令 1、算术左移指令SAL 功能&#xff1a;左移一次&#xff0c;最低位补0&#xff0c;最高位送入CF标志位&#xff0c;如图&am…

汇编指令(四)移位指令

学习概要 格式 移位指令主要分四种 一、逻辑移位指令 1.逻辑左移指令SHL 2.逻辑右移指令SHR 3.逻辑移位指令的功能 二、算术移位指令 1.算术左移指令SAL 2.算术右移指令SAR 最高位不变的意思就是&#xff0c;最高位原来是1&#xff08;0&#xff09;&#xff0c;右移过后…

【大学生软件测试基础】白盒测试 - 语句覆盖 - 03

任务1、依据源代码画出程序流程图&#xff1b; 任务2、根据程序流程图&#xff0c;找出程序的所有执行路径&#xff1b; 任务3、找出能覆盖所有语句的最少路径&#xff1b; 任务4、根据最少路径设计语句覆盖用例&#xff1b; 流程图&#xff1a; 任务2、根据程序流程图&…

修正的判定条件覆盖例题_语句覆盖、判断覆盖、条件覆盖、条件判定组合覆盖、多条件覆盖、修正条件覆盖...

int function(bool a,bool b,boolc){intx; x=0;if(a&&(b||c)){x=1;returnx; } } 1、语句覆盖(SC) 选择足够多的测试数据,使得被测程序中的每条语句至少执行一次。 测试用例:a=T,b=T,c=T 2、判断覆盖(DC) 设计足够的测试用例,使得程序中的每个判定至少都获得一次真值…

语句覆盖,判定覆盖,条件覆盖,条件/判定覆盖,条件组合覆盖,路径覆盖

最近在复习软件测试的考试&#xff0c;每次到白盒测试这里都要为这几种逻辑覆盖方法感到头疼&#xff0c;这次终于决定好好整理出来。 逻辑覆盖是通过对程序逻辑结构的遍历实现程序的覆盖。它是一系列测试过程的总称&#xff0c;这组测试过程逐渐进行越来越完整的通路测试。 根…

软件测试培训之:白盒测试的语句覆盖法和判定覆盖法

白盒测试是相对于黑盒测试而言的&#xff0c;黑盒测试不关注程序内部的实现结构&#xff0c;仅仅是通过向程序进行输入来观察程序的输出对不对;白盒测试就需要关注程序内部的实现结构&#xff0c;对程序的逻辑结构实施相关的测试;那么下面来谈谈语句覆盖法、判定覆盖法和条件覆…

语句覆盖、判定覆盖、条件覆盖 - 白盒笔试题解析

1. 定义 黑盒测试 - 不关注内部结构的测试/基于输入输出的测试 白盒测试 - 基于内部结构的测试 白盒测试的关键&#xff1a; 覆盖度 2. 白盒相关概念 语句覆盖 - 设计一套测试 让被测对象中所有语句得到测试覆盖 判定覆盖 - 设计一套测试 让被测对象中所有判定得到测试覆…

白盒测试用例设计方法(语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖、路径覆盖、基本路径覆盖)

语句覆盖&#xff1a;每条语句至少执行一次。 判定覆盖&#xff1a;每个判定的所有可能结果至少出现一次。&#xff08;又称“分支覆盖”&#xff09; 条件覆盖&#xff1a;每个条件的所有可能结果至少执行一次。 判定/条件覆盖&#xff1a;一个判定中的每个条件的所有可能结果…

白盒测试的逻辑覆盖辨析(语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖)

白盒测试逻辑覆盖&#xff08;语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖&#xff09; 逻辑覆盖测试&#xff1a; 语句覆盖&#xff1a;每条语句至少执行一次判定覆盖&#xff1a;每一判定的每个分支至少执行一次条件覆盖&#xff1a;每一判定中的每个条件&…

白盒测试技术——语句覆盖、判定覆盖、条件覆盖

结合一个例子说&#xff1a; 画出相应的程序流程图&#xff0c;更方便分析&#xff1a; 首先我们要明确一点&#xff1a;测试用例要尽可能少。 1、语句覆盖&#xff1a;被测程序中每个语句至少执行一次 路径&#xff1a;s->a->b->c->d->e A2&#xff0c;B0&a…

语句覆盖、分支覆盖、谓词测试和路径覆盖

目录 语句覆盖分支覆盖&#xff08;判定覆盖&#xff09;谓词测试原子谓词覆盖&#xff08;条件覆盖&#xff09;分支-谓词覆盖(判定条件覆盖或分支条件覆盖)复合谓词覆盖&#xff08;条件组合覆盖&#xff09; 路径覆盖包含关系 语句覆盖 “语句覆盖”是一个比较弱的测试标准…

白盒测试 | 用例设计方法之语句覆盖

语句覆盖&#xff0c;顾名思义就是针对代码语句的嘛。它的含义是我们设计出来的测试用例要保证程序中的每一个语句至少被执行一次。通常语句覆盖被认为是“最弱的覆盖”&#xff0c;原因是它仅仅考虑对代码中的执行语句进行覆盖而没有考虑各种条件和分支&#xff0c;因此在实际…

逻辑覆盖测试(一)语句覆盖

语句覆盖&#xff1a; 设计测试用例时保证程序的每条语句至少执行一次。 简单来说&#xff0c;就是每个语句都覆盖一遍。 例子&#xff1a; 流程图如下&#xff1a; 测试用例如下&#xff1a; x4,z9&#xff0c;第一个if语句执行到了&#xff1b; x4,y7,第二个if语句为true…

设计测试用例实现语句覆盖,判定覆盖,条件覆盖,判定/条件覆盖,条件组合覆盖,路径覆盖.

第一题&#xff1a; 设计测试用例实现语句覆盖,判定覆盖,条件覆盖&#xff0c;判定/条件覆盖,条件组合覆盖,路径覆盖. 【1】语句覆盖&#xff08;设计若干个测试用例&#xff0c;使程序中的每个可执行语句至少执行一次&#xff09; &#xff08;x>3&#xff09;&&&…