初识汇编指令

1. ARM汇编指令

目的 认识汇编, 从而更好的进行C语言编程 

RAM指令格式:  了解 

4字节宽度  地址4字节对齐    方便寻址 

1.1 指令码组成部分 :

condition:  高4bit[31:28]  条件码  0-15 16个值 

条件码: 用于指令的 条件执行 , ARM指定绝大部分 都可以条件执行 

可以让程序 不必要跳转 而执行分支结构  不打断流水线 效率更高   

指令操作码:  [24:21]  指令本身的 编号  可以有16种指令 

Rn: 第一操作寄存器  第一个操作对象寄存器    

Rd: 目标寄存器      用于存放输出结果的寄存器 

Rm: 第二操作寄存器 或 立即数 或 立即数移位

S位:  用于指定 该指令 是否记录其状态到 CPSR中 

1.2汇编编程格式: 

1. 汇编指令    编译后将 生成一条对应值 指令码  

2. 汇编伪指令  编译后将  生成一条或多条指令码 

3. 汇编操作(标志符号)   .text  .end  ... 

.text  汇编代码段开始  属于汇编操作
mov r0,#1   @ 汇编指令  
.data  汇编数据段开始 
.end   汇编代码结束

1.3 汇编中的类型: 

 ARM 约定:

  Byte: 8bits(1byte)    字节      char

  Halfword: 16bits(2byte)  半字    short

  Word: 32bits(4byte) 字     int

  Doubleword: 64bits (cortex-a) 

2. 数据搬移指令

mov  mvn  

2.1 立即数

使用12bit 按规则可以存放的数 称立即数

0 - 2^12-1   即最大2048 

12bit分两部分   高4bit 存放 循环右移的偶数次

低8bit 存放 右移的数本身

立即数定义:  一个数 可以通过一个8bit(最大255)数  循环右移偶数位得到, 该数即立即数 目的 扩大了 可以输入的值的 值域范围  即  0-2^32  但不连续 

2.1.1 举例

指令 mov r0,#0xff000

汇编如下

0x00000000  E3A00AFF  MOV       R0,#0x000FF000

立即数0xff000二进制如下

0000 0000 0000 1111 1111 0000 0000 0000

靠1111 1111  循环右移 10*2 = 20位得到 

0000 0000 0000 1111 1111 0000 0000 0000    

小知识 :

循环右移:  桶型移位器  硬件设备  

2.1.2 练习:  判断下列数 是否为立即数 

(1) 100(十进制) 是 (因为100 8个bit就能装下,移不移位不影响的)

(2)  0x F000000F      是    0xff 循环右移 4位  是立即数 

解释,汇编如下

0x00000000  E3A002FF  MOV       R0,#0xF000000F

靠000000FF  右移4位 得到立即数 ----->  F000000F

二进制的写法

0000 0000 0000 0000 0000 0000 1111 1111   

右移4位  ----->  1111 0000 0000 0000 0000 0000 0000 1111

(3)  0X 0F0F0F0F 不是立即数  (因为中间的0不可能靠移位能够得到)

(4)  0X 12300 不是立即数 (因为右移的本身数部分8个bit怎么都装不下)

解释

0X 12300 二进制如下

0000 0000 0000 0001 0010 0011 0000 0000 

黄色部分8个bit装不下,至少9个bit了,不符合立即数定义

(5)  0x 12c00        是 

0000 0000 0000 0001 0010 1100 0000 0000 

黄色部分7个bit可以装下,符合定义

本身数0100 1011 = 4b开始循环右移,写满32位如下

0000 0000 0000 0000 0000 0000 0100 1011 右移 4 如下

1011 0000 0000 0000 0000 0000 0000 0100  右移 8 如下

0100 1011 0000 0000 0000 0000 0000 0000  右移 16 如下

0000 0000 0100 1011 0000 0000 0000 0000  右移22 如下

00 00|00 00|00 00|00 01|00 10|11 00|00 00|00 00

规整

  0          0       0        1         2       C        0        0

看看汇编如下,双数分析正确

0x00000000  E3A00B4B  MOV       R0,#0x00012C00

(6)  0X 1060    不是 

0000 0000 0000 0000 0001 0000 0110 0000 

虽然红字刚好8个bit可以装下,但是前面的0(黄色部分的个数是奇数个,不符合立即数规定)

2.2 有效数

2.2.1 装载0x FFFFFFFF

mov r0,#0xffffffff   (这里的0xffffffff就是有效数)

汇编如下

0x00000000  E3E00000  MVN       R0,#0x00000000

可以看到 mov 编程mvn 了

mvn 将数 进行取反后在进行装载 

有效数: 一个数取反后是立即数

2.2.2装载 0x12345678

这个程序直接报错,因为无论是立即数还是有效数,都无法装载

但是 使用伪指令可以装载

2. 伪指令: 

暂时了解即可

ldr r0,=0x12345678

汇编如下

0x00000004  E51F0004  LDR       R0,[PC,#-0x0004]

偏移

3. 移位操作指令: 

lsl 逻辑左移:  对无符号数操作  <<   高位移出丢弃  低位补0 

lsr 逻辑右移:  对无符号数操作  >>   低位移出丢弃  高位补0 

asr 算数右移:  对有符号数操作  >>   低位移出丢弃  高位补符号位 

ror 循环右移:  低位移出  补充到高位 

3.1逻辑左移和逻辑右移

@移位操作 
mov r0,#1
lsl r1,r0,#2 @相当于c语言的r1 = r0<<2;  左移相当于做乘法 R0 * 2^2
lsr r2,r1,#1 @相当于c语言的r2 = r1>>2;  右移相当于做除法 R1 / 2^1

3.2 C语言实现循环右移:

unsigned int  ROR(unsigned int a, char cnt)
{
	int f = 0;
	while(cnt--)
	{
		f =  a & 1;  //取出低位
		a >> 1;     // 右移 
		a = a | (f << 31);  // 补充高位
	}
}

3.2 算数右移

@算数右移
ldr r3,=-5
asr r4,r3,#1   @ 算数右移1位 R3 / 2^1

1111 1111 1111 1111 1111 1111 1111 1011   = -5  右移一位如下 低位移出丢弃  高位补符号位

1111 1111 1111 1111 1111 1111 1111 1101      = -3        

4. 算数指令: 

在指令后+s 后缀 表示该指令若存在进位 要影响CPSR中的nzcv位 

add   加法 

adc   带进位加法 

sub   减法 

sbc   带借位减法 

rsb   逆向减法

rsc   带借位逆向减法 

mul   乘法指令 

举例

@ 算数运算 
MOV R0, #5
MOV R1, #2
ADD R1,R0   @相当于c语言的r1 += r0

4.1练习 

4.1.1  32位寄存器 实现64位加减法:

a = 0x12345678 87654321 

b = 0x12345678 88888888 

加法

r0 高32bit  r1 低32bit 

@32位寄存器 实现64位加法: a = 0x12345678 87654321   b = 0x12345678 88888888 
ldr r0,=0x12345678 @使用伪指令分开装
ldr r1,=0x87654321
ldr r2,=0x12345678
ldr r3,=0x88888888 

adds r5,r1,r3  @ 计算低32位  s 表示cpsr要存储进位标志 
adc  r4,r0,r2  @ 计算高32位  R4 = R0+R2+进位标志

a = 0x12345678 87654321 

b = 0x12345678 88888888 

a+b 0x2468acf1 0fedcba9

减法
@ 练习实现 a-b 
subs r5,r1,r3  @ 计算低32位  R5=R1-R3
sbc  r4,r0,r2  @ 计算高32位

a = 0x12345678 87654321 

b = 0x12345678 88888888 

a-b 0xffffffff  fedcba99  

4.1.2 逆向减法指令

按规定立即数必须在最后面 比如这样sub r1,r0,#5  不能写成sub r1,#5,r0

但是我们的需求是实现 5-r0  这个时候就使用rsb r2,r0,#5

@逆向减法指令
mov r0,#10
@sub r1,r0,#5   @ r1=r0-5; @按规定立即数必须在最后面 比如这样sub r1,r0,#5  不能写成sub r1,#5,r0
rsb r2,r0,#5   @ r1 = 5-r0

FFFF FFFB  补码

FFFF FFFA  反码  

0000 0005   源码   即 -5

4.1.3 乘法指令

@乘法指令
mov r0,#10
mov r1,#5
mul r3,r0,r1   @ r0=r0*r1   这里r3等于  50

5. 位运算

位运算  C语言:  & 按位与

| 按位或   

^ 按位或    

~ 按位取反       ( mvn在汇编中既可以搬运数据也可以取反)

and       orr         eor 

逻辑运算: !非  &&逻辑与   ||逻辑或  

and   &     按位操作    与0得0    与1不变 

@与运算
mov r0,#0xff
and r1,r0,#0xf

orr   |             按位操作    或1得1  或0不变 

@或运算
mov r0,#0xff
orr r1,r0,#0xf

eor   ^             按位操作    相同为0  不同为1 

@异或运算
mov r0,#0xff
eor r1,r0,#0xf

5.1 位运算的 应用:

5.1.1 有一个数 a  [31:0]  希望 其中 [7:4] = 0 其他bit不变 

a = **** **** **** **** **** **** [****] ****

a & 1111 1111 1111 1111 1111 1111  0000  1111 ---->  即 ~ 1111 0000 

a & ~ 1111 0000

a = a & ~ (0xf << 4);

  = **** **** **** **** **** **** [0000] ****

5.1.2 有一个数 a  [31:0]  希望 其中 [7:4] = 0x7 其他bit不变 

a = **** **** **** **** **** **** [****] ****

a & 1111 1111 1111 1111 1111 1111  0000  1111

  = **** **** **** **** **** **** [0000] ****

a | 0000 0000 0000 0000 0000 0000  0111  0000 

a | (0x7 << 4)

  = **** **** **** **** **** **** [0111] ****

 a = (a & ~ (0xf << 4)) | (0x7 << 4);

5.1.3 有一个数 a  [31:0]  希望 其中 [18:9] = 0x123  其他bit不变 

 a = **** **** **** *[*** **** ***]* **** ****

  & ~(0x3ff << 9); 

 a = **** **** **** *[000 0000 000]* **** **** 

   | (0x123 << 9)

a = (a & ~ (0x3ff << 9)) | (0x123 << 9);

5.1.4 规律(重点)

有一个数 a  [31:0]  希望 其中 [m:n] = x 其他bit不变 

a = (a & ~ ( P << n)) | (x << n);   其中 P= 2^(m-n+1) - 1;  P本质是 位宽这么多个1的值

6. 位操作指令

bic  位清除指令  用于清除指定的位

6.1 bic位清除指令

bic  位清除指令  用于清除指定的位

bic的规律是 遇见  0  不变    遇见1  清0  

@位操作指令bic
@清除4-7位为0
mov r0,#0xff
bic r1,r0,#0xf0 @ 类似于 R1=R0 & ~(0XF0)

6.2 条件码

条件执行与 条件码:   在指令后边 添加条件后缀  表示条件执行 

共有16种条件  以下是常用的

EQ   相等执行 

NE   不相等执行 

有符号数比较

GT   > 

GE   >= 

LT   < 

LE   <= 

6.3 比较指令: 

执行结果 在 CPSR 中的 NZCV位体现  不需要目标寄存器 

----->>>

TST   测试指定位 是否为0

cmp   比较大小   >   <    ==    !=    >=    <= 

teq   比较相等否   ==   != 

6.2.1 cmp

if(a > 0)
	a= 5;
else        // <= 0
	a= 6;

将上述代码编译成汇编代码

@比较指令  与  条件指令
@ if(a > 0)
@	a= 5;
@ else        // <= 0
@	a= 6;
@将上述代码改写为汇编

mov r0,#2
cmp r0,#0  @比较r0  与  0的关系
movgt r0,#5  @意思是如果r0>0 就将r0赋值为5
movle r0,#6  @意思是如果r0<=0 就将r0赋值为6

NOP   @ 空指令  MOV R0,R0  浪费时间 

7.  跳转指令: 

b   : 不带链接的跳转   类似 goto 

bl  : 带链接的跳转  就是 跳转时 会 将PC指针备份到 lr寄存器中 

7.1   b指令

这段代码的意思就是  在开始设置了一个loop地址标记,在最后 b loop 在此跳转到地址标记处执行代码

loop: @地址标记
mov r0,#2
cmp r0,#0  @比较r0  与  0的关系
movgt r0,#5  @意思是如果r0>0 就将r0赋值为5
movle r0,#6  @意思是如果r0<=0 就将r0赋值为6

NOP   @ 空指令  MOV R0,R0  浪费时间 
b loop @ 跳转到标记loop出开始执行

7.1.1 汇编实现:求 1+2+3 +.. 100 = ???

c实现

for(int i =1, sum = 0; i<= 100; i++)  
    sum += i;

汇编如下

@汇编实现求 1+2+3 +.. 100 = ???
@ for(int R0 =1, R1 = 0; R0 <= 100; R0++)  R1 += R0;

mov r0,#1 @给r0 为1 
mov r1,#0 @给r1 为0  用来存储结果
loop:  @地址标记
cmp r0,#100  @比较r0 和 100 的大小
addle r1,r0  @如果r0 <= 100  就执行 r1 = r1+r0
addle r0,#1	 @如果r0 <=100  就执行 r0 = r0+1
ble loop   @ 只有条件满足时(r0 <= 100 )才会 跳转到标记loop出开始执行(不满足则跳出即r0 > 100)

NOP 

@汇编实现求 1+2+3 +.. 100 = ???
for(int R0 =1, R1 = 0; R0 <= 100; R0++)  R1 += R0;

mov r0,#1 @给r0 为1 
mov r1,#0 @给r1 为0  用来存储结果
loop:  @地址标记
cmp r0,#100  @比较r0 和 100 的大小
addle r1,r0  @如果r0 <= 100  就执行 r1 = r1+r0
addle r0,#1	 @如果r0 <=100  就执行 r0 = r0+1
ble loop   @ 只有条件满足时(r0 <= 100 )才会 跳转到标记loop出开始执行(不满足则跳出即r0 > 100

NOP 

7.1.2  练习

编译如下C代码为汇编指令: 

switch(a)

{

case 1: a=5; break;

case 2: a=6;

case 3: a=7; break;

default: a=10;

}

mov r0,#1
teq r0,#1  @ case 1:
moveq r0,#5 @相等时执行
beq _end  	@break

teqne r0,#2 @  如果case 1未命中(r0不等于1),则继续比较r0中的值是否等于2。
moveq r0,#6  @ a = 6 如果比较结果相等(teqne指令执行后,r0等于2),则执行这行指令

teqne r0,#3  @ 如果case 2未命中(r0不等于2),则继续比较r0中的值是否等于3。
moveq r0,#7  @ 如果比较结果相等(teqne指令执行后,r0等于3),则执行这行指令。
beq _end  	@break @ 如果在case 3中执行了moveq指令(r0被设置为7),则跳转到标签_end处。

movne R0,#10   @default  @ 如果前面的case都未命中(r0不等于1、2或3),则执行这行指令。
					@ movne指令在不相等(not equal)条件下,将立即数10(#10)移动到r0寄存器中

_end:
nop

7.2 bl指令

主要作用于函数调用 

c语言

int addNum(int a,int b, int c)
{
	return a+b+c;
}	
a = addNum(1,2,3);	

汇编实现

C语言标准规范: 

规定 函数的调用  参数 前4个参数使用 r0-r3传递  ,超过4个的参数 使用栈传递 

返回值 通过R0传递 

@bl指令实现 定义函数
@int addNum(int a,int b, int c)
@{
@	return a+b+c;
@}	
@a = addNum(1,2,3);

@准备参数
mov r0,#1
mov r1,#2
mov r2,#3
@调用函数
bl addNum
nop
nop

@定义函数
addNum:  @r0,r1,r2 3个参数
add r0,r1
add r0,r2
mov pc,lr  @相当于return 这里返回到nop了就是bl addNum 调用函数的下一条指令

7.3 b,bl指令的特点: 

1.b/bl指令 是一个相对跳转指令  相对当前取址的指令位置  向前或先后 跳转  指定的指令条数

2.b/bl指令  最大可以跳转的 地址空间 为  +- 32M 

指令除去 8BIT的条件码与指令码  剩余24bit 用于存储跳转的 指令条数 

Linux程序地址空间 0-4G

b/bl属于短跳转  +- 32M 

长跳转/绝对跳转  直接将要跳转的内存地址 加载到PC寄存器中 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/343861.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Linux之快速入门(CentOS 7)

文章目录 一、Linux目录结构二、常用命令2.1 切换用户2.2查看ip地址2.3 cd2.4 目录查看2.5 查看文件内容2.6 创建目录及文件2.7 复制和移动2.82.93.0 一、Linux目录结构 目录作用/bin是 Binaries (二进制文件) 的缩写,这个目录存放着最经常使用的命令/dev是 Device(设备) 的缩写…

【GitHub项目推荐--不错的Rust开源项目】【转载】

01 Rust 即时模式 GUI 库 egui 是一个简单、快速且高度可移植的 Rust 即时模式 GUI 库&#xff0c;可以轻松地将其集成到你选择的游戏引擎中&#xff0c;旨在成为最易于使用的 Rust GUI 库&#xff0c;以及在 Rust 中制作 Web 应用程序的最简单方法。 项目地址&#xff1a;ht…

go 依赖注入设计与实现

在现代的 web 框架里面&#xff0c;基本都有实现了依赖注入的功能&#xff0c;可以让我们很方便地对应用的依赖进行管理&#xff0c;同时免去在各个地方 new 对象的麻烦。比如 Laravel 里面的 Application&#xff0c;又或者 Java 的 Spring 框架也自带依赖注入功能。 今天我们…

【ASOC全解析(一)】ASOC架构简介和欲解决的问题

【ASOC全解析&#xff08;一&#xff09;】ASOC架构简介和欲解决的问题 一、什么是ASOC以及ASOC解决的三个问题二、ASOC的组成与功能解决第一个问题解决第二个问题解决第三个问题 三、ASOC基本工作原理 /********************************************************************…

Parade Series - Android Studio

硬件支持 CPU i7 RAM 16Gb -------------- ------- Java 3Gb Android 33GbJava Enviroment C:\ ├─ Java │ ├─ jdk1.8.0_181 │ ├─ jre1.8.0_181 │ ├─ maven-3.8.5 │ └─ gradle-6.5 └─ Cache├─ gr…

基于中文垃圾短信数据集的经典文本分类算法实现

垃圾短信的泛滥给人们的日常生活带来了严重干扰&#xff0c;其中诈骗短信更是威胁到人们的信息与财产安全。因此&#xff0c;研究如何构建一种自动拦截过滤垃圾短信的机制有较强的实际应用价值。本文基于中文垃圾短信数据集&#xff0c;分别对比了朴素贝叶斯、逻辑回归、随机森…

哈希--73. 矩阵置零/medium 理解度A

73. 矩阵置零 1、题目2、题目分析3、复杂度最优解代码示例4、适用场景 1、题目 给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,…

Overleaf(LaTeX文档在线编写平台)使用学习记录

一、LaTeX简概[1] LaTeX&#xff0c;是一种基于TEX的排版系统&#xff0c;是一种可以处理排版和渲染的标记语言。由美国计算机科学家莱斯利兰伯特在20世纪80年代初期开发&#xff0c;利用这种格式系统的处理&#xff0c;即使用户没有排版和程序设计的知识也可以充分发挥由TEX所…

CACTER邮件安全网关独家安全解决方案——保障企业邮件系统安全

随着科技的不断发展&#xff0c;网络攻击技术也在不断演变&#xff0c;尤其是在电子邮件领域&#xff0c;各种高级变种威胁层出不穷&#xff0c;比如定制化的钓鱼邮件和带有高级恶意软件的邮件等。这些威胁邮件往往能够绕过传统的安全防护措施&#xff0c;包括反垃圾邮件、反钓…

软件安全测试的重要性简析,专业安全测试报告如何申请?

在当今数字化时代&#xff0c;软件在我们的日常生活中扮演着至关重要的角色&#xff0c;但也带来了各种潜在的安全威胁。为了保障用户的信息安全和维护软件的可靠性&#xff0c;软件安全测试显得尤为重要。 软件安全测试是指通过一系列的方法和技术&#xff0c;对软件系统中的…

pikachu_csrf通关攻略

csrf&#xff08;get&#xff09; 打开pikachu靶场&#xff1a; 1. 根据提示给的账户密码进行登录 2. 打开代理拦截数据包将拦截数据发送到已打开的burp中&#xff1a; 修改数据进行发包&#xff1a; 从上面的url可见&#xff0c;修改用户信息的时候&#xff0c;是不带任何不…

性能优化(CPU优化技术)-NEON指令介绍

「发表于知乎专栏《移动端算法优化》」 本文主要介绍了 NEON 指令相关的知识&#xff0c;首先通过讲解 arm 指令集的分类&#xff0c;NEON寄存器的类型&#xff0c;树立基本概念。然后进一步梳理了 NEON 汇编以及 intrinsics 指令的格式。最后结合指令的分类&#xff0c;使用例…

如何基于 ESP32 芯片测试 WiFi 连接距离、获取连接的 AP 信号强度(RSSI)以及 WiFi吞吐测试

测试说明&#xff1a; 测试 WiFi 连接距离&#xff0c;是将 ESP32 作为 WiFi Station 模式来连接路由器&#xff0c;通过在开阔环境下进行拉距来测试。另外&#xff0c;可以通过增大 WiFi TX Power 来增大连接距离。 获取连接的 AP 信号强度&#xff0c;一般可以通过 WiFi 扫描…

机器学习_从线性回归到逻辑回归原理和实战

文章目录 介绍分类问题用线性回归阶跃函数完成分类通过 Sigmiod 函数进行转换逻辑回归的假设函数逻辑回归的损失函数用逻辑回归解决二元分类问题 介绍分类问题 机器学习两个主要应用是回归和分类问题。 逻辑回归算法的本质其实仍然是回归。这个算法也是通过调整权重w和偏置b来…

GBASE南大通用提供给.NET 应用程序访问 GBase 数据库、获取数据、管理数据的一套完整的解决方案

GBase ADO.NET&#xff08;全称是 .NET Framework Data Provider For GBase&#xff09;提 供给.NET 应用程序访问 GBase 数据库、获取数据、管理数据的一套完整的解决 方案。 GBase ADO.NET 的四个核心类及若干功能类具有以下功能&#xff1a;  建立和管理与 GBase 数据库连…

java web mvc-04-Apache Wicket

拓展阅读 Spring Web MVC-00-重学 mvc mvc-01-Model-View-Controller 概览 web mvc-03-JFinal web mvc-04-Apache Wicket web mvc-05-JSF JavaServer Faces web mvc-06-play framework intro web mvc-07-Vaadin web mvc-08-Grails 开源 The jdbc pool for java.(java …

21.云原生之ArgoCD CICD实战(部分待补充)

云原生专栏大纲 文章目录 部署项目介绍项目结构介绍GitLab CI/CDGitLab CI/CD主要特点和功能 部署测试argocd的cd过程CICD工作流准备工作github中工作流文件创建gitlab中工作流文件创建【实操待补充】GitLab CI示例 数据加密之seale sealedBitnami Sealed Secrets介绍Bitnami …

11.前端--CSS-背景属性

1.背景颜色 样式名称&#xff1a; background-color 定义元素的背景颜色 使用方式: background-color:颜色值; 其他说明&#xff1a; 元素背景颜色默认值是 transparent&#xff08;透明&#xff09;      background-color:transparent; 代码演示&#xff1a; 背景色…

盖子的c++小课堂:第二十六讲:双向链表

前言 谢谢各位粉丝的支持,望我早日突破1000粉 双向链表 干货!单链表从原理到实现——附python和C++两个版本 - 知乎单链表是链表家族中的一员,每个节点依旧由 数据域(data)和指针域(next)组成,链表的具体概念下面有介绍: 机器学习入坑者:程序员基本功——链表的基…

大数据学习之Flink算子、了解(Source)源算子(基础篇二)

Source源算子&#xff08;基础篇二&#xff09; 目录 Source源算子&#xff08;基础篇二&#xff09; 二、源算子&#xff08;source&#xff09; 1. 准备工作 2.从集合中读取数据 可以使用代码中的fromCollection()方法直接读取列表 也可以使用代码中的fromElements()方…