Linux 学习记录52(ARM篇)

这篇具有很好参考价值的文章主要介绍了Linux 学习记录52(ARM篇)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Linux 学习记录52(ARM篇)

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

一、汇编语言相关语法

1. 汇编语言的组成部分

1.伪操作
    不参与到程序的执行,但是可以告诉编译器程序应该怎么执行,或者程序中每一个部分有什么含义
    .text .global  .globl .end  .if .else .endif   
2.汇编指令
    编译器将一条汇编指令编译成一条机器码,执行指令后可以让ALU做出对应的运算操作,实现特定的功能
3.伪指令
    不是汇编指令,但是可以起到和汇编指令一样的作用,通常一条伪指令的实现需要多条汇编指令一起完成
    
4.汇编里的注释:
    单行注释:使用@  其他架构下的汇编单行注释 可能会使用';'
    多行注释:/**/
    条件注释:根据if后面的数值真假来去执行不同的指令段,如果为真,执行指令段1,否则执行指令段2
        .if 数值
            指令段1
        .else
            指令段2
        .endif                

2. 汇编指令的类型

  1. 基本的数据处理指令
  1. 数据搬移指令
  2. 数据移位指令
  3. 算数运算指令
  4. 位运算指令
  5. 比较指令
  1. 跳转指令
  2. 内存读写指令
  3. 程序状态寄存器读写指令
  4. 软中断指令

3. 汇编指令的使用格式

格式:opcode{cond}{s}  Rd, Rn, shifter_operand

解释:
opcode : 指令码  
cond : 条件码  
    默认汇编指令是无条件执行的,使用条件码之后可以让汇编有条件的执行
s: 状态位  
    指令的执行结果会影响cpsr的NZCV位   
Rd : 目标寄存器 
    运行的结果放到目标寄存器
Rn : 第一个操作寄存器,只能是一个寄存器

shifter_operand : 第二个操作数 
    1> 可以是一个普通的寄存器
    2> 可以是一个立即数
    3> 可以是经过移位操作的寄存器
opcode{cond}{s} : 连到一起写
Rd, Rn, shifter_operand : 使用逗号隔开
opcode{cond}{s}和Rd, Rn, shifter_operand直接使用空格隔开

一条汇编指令占一行;
汇编代码中不严格区分大小写: 

二、基本数据处理指令

1. 数据搬移指令

(1. 格式

opcode{cond}{s}    Rd,       shifter_operand
指令码           目标寄存器      操作数

(2. 指令码类型

1. mov:将操作数搬移到寄存器中
2. mvn:将操作数按位取反后搬移到目标寄存器中

(3. 使用示例

.text   
.global _start
_start:
    mov r0,#0XFF  @将0XFF搬移到r0寄存器中
    mvn r1,#0XFF  @将0XFF按位取反结果存放到R1寄存器中
    
stop:
    b stop   
.end 

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发
Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

2. 立即数

能够当作指令的一部分去执行的数据叫做立即数。一个立即数可以通过一个0-255之间的数字进行循环右移得到

如何判断一个数据是不是立即数:
在0-255内找到一个数据,将数据循环右移偶数位,如果能够得到这个数据,就说明这个数据是一个立即数
ex1:0X104->二进制:0000 0000 0000 0000 0000 0001 0000 0100
找到一个0-255范围内的数:0000 0000 0000 0000 0000 0000 0100 0001——》0X41
0x41循环右移30位可以得到0X104,所以0X104就是立即数

ex:0X101->二进制:0000 0000 0000 0000 0000 0001 0000 0001

(1. 一条指令的组成

在32位下一条指令大小为32字节

[0:7] "0-255的数据 进行循环右移的数据,通过这个数据循环右移偶数位可以得到第二操作数"
[8:11] "低八位循环右移的偶数位对应拖偶数由这个区间的数值*2得到"
[12:15] "Rd 目标寄存器标识"
[16:19] "Rn 操作寄存器标识"
[20:21] "s 状态位"
[22:25] "opcond 指令码"
[26:27] "001"
[28:31] "cond 条件码"

注意:对于立即数的判断,如果数据mov指令的操作数>0XFFFF0000,则在计算机处理时,按照MVN指令进行判断
Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

可以使用伪指令
Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

3. 移位操作指令

(1. 格式

格式:opcode{cond}{s}  Rd, Rn, shifter_operand

解释:
opcode : 指令码  
cond : 条件码  
    默认汇编指令是无条件执行的,使用条件码之后可以让汇编有条件的执行
s: 状态位  
    指令的执行结果会影响cpsr的NZCV位   
Rd : 目标寄存器 
    运行的结果放到目标寄存器
Rn : 第一个操作寄存器,只能是一个寄存器

shifter_operand : 第二个操作数 

(2. 指令码类型

1. 左移运算 低位补0
2. lsr:右移运算  高位补0
3. ror:循环右移  低位移出的数据补到最高位

(3. 使用示例

.text   
.global _start   
    
_start:
    mov r0,#0XFF
    lsl r1,r0,#4  @ 将r0的值左移4位结果放到r1中 R1==0XFF0
    lsr r2,r0,#4  @将r0的值右移4位结果放到r2中 R2==0XF
    ror r3,r0,#4   @ 将r0的值循环右移4位结果放到r3中 R3==0XF000000F
stop:
    b stop   
.end  

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

4. 位运算指令

(1. 格式

格式:opcode{cond}{s}  Rd, Rn, shifter_operand

解释:
opcode : 指令码  
cond : 条件码  
    默认汇编指令是无条件执行的,使用条件码之后可以让汇编有条件的执行
s: 状态位  
    指令的执行结果会影响cpsr的NZCV位   
Rd : 目标寄存器 
    运行的结果放到目标寄存器
Rn : 第一个操作寄存器,只能是一个寄存器

shifter_operand : 第二个操作数 

(2. 指令码

1. and:按位与  与0清0,与1不变
2. orr:按位或  或1置1 或0不变
3. eor:按位异或  相同为0 不同为1
4. bic:按位清0  想要哪一位设置为0,只需要将这一位用bic指令和相同位为1的数进行运算

(3. 运算规则

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

(4. 使用示例

.text   
.global _start   
    
_start:
    mov r0,#0XFF
    and r1, r0,#0XF  @r1==0XF
    orr r2,r0,#0XF00  @r2==0XFFF
    eor r3,r0,#0XF  @R3==0XF0
    bic r4,r0,#0X14 @R4==0XEB       
stop:
    b stop   
.end  

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

(5. 练习

LDR r0,=0X12345678
 0001 0010 0011 0100 0101 0110 0111 1000
1.将r0寄存器的第4位清0,其他位不变
bic r0,r0,#(1<<4)
或者
and r0,r0,#(~(1<<4))

2.将R0寄存器的第7位置1,其他位不变
 orr r0,r0,#(1<<7)

3.将r0寄存器的第[31:28]0,其他位不变
bic r0,r0,#(0XF<<28)

4.将r0寄存器第[7:4]位置1,其他位不变
ORR r0,r0,#(0XF<<4)

5.将R0寄存器的第[15:11]位设置为10101,其他位不变
思路:把指定的几位设置为特定的数值,先把这几位清0,在赋值
BIC r0,r0,#(0X1F<<11)@先清0
ORR r0,r0,#(0X15<<11)@再赋值

5. 算数运算指令

(1. 格式

格式:opcode{cond}{s}  Rd, Rn, shifter_operand

解释:
opcode : 指令码  
cond : 条件码  
    默认汇编指令是无条件执行的,使用条件码之后可以让汇编有条件的执行
s: 状态位  
    指令的执行结果会影响cpsr的NZCV位   
Rd : 目标寄存器 
    运行的结果放到目标寄存器
Rn : 第一个操作寄存器,只能是一个寄存器

shifter_operand : 第二个操作数 

(2. 指令码

1. add :进行加法运算
2. adc:进行加法运算的时候考虑到CPSR的c位 
3. sub:进行减法运算
4. sbc:进行减法运算时考虑到CPSR的C位
5. mul:乘法运算

(3. 使用示例

1.加法1:
    MOV r0,#1
     mov r1,#3
    add r2,r0,r1 @将r0+r1的结果存放r2寄存器
2.加法2:
    MOV r0,#0XFFFFFFFE
    mov r1,#3
    adds r2,r0,r1 @将r0+r1的结果存放r2寄存器,+s结果进位就会影响到CPSR的c位

3.减法运算
MOV r0,#3
    mov r1,#0XFFFFFFFE
    subs r2,r0,r1 @将r0-r1的结果存放r2寄存器

(4. 关于32位的处理器进行64位数据的运算原理

原理:一个64位的数据放在两个寄存器中,分别存放这个数据的高64位以及低64位
进行64位数据运算时,将两个64位数据的低32位运算,高32位运算

以加法为例子:
    MOV r0,#0X3  @第一个64位数的低32位 
    mov r1,#0X1 @第一个数的高32位
    mov r2,#0XFFFFFFFE @第2个64位数的低32位
    mov r3,#0X4 @第二个64位数据的高32位
    adds r4,r0,r2 @两个低32位数运算,结果影响到CPSR的C位
    adc r5,r1,r3 @两个高32位数据运算,结果存放在r5中,考虑到C位

6. 比较指令

(1. 概述

格式:
opcode Rn, shifter_operand
opcode:比较指令的指令码是cmp
功能:将第一操作寄存器和第二操作数的值进行比较
本质:比较指令的本质就是拿进行比较的两个数值进行减法运算,并且减法运算的结果会影响到CPSR的条件位
我们可以根据条件位的数值进行两个数值的判断,再根据判断的结果做不同的操作
一般比较指令和条件码都是一起使用的

(2. 比较指令结果的条件码

条件码 助记符后缀 标志 含义
0000 eq z置位 相等
0001 ne z清零 不相等
0010 cs c置位 无符号数大于或等于
0011 cc c清零 无符号数小于
0100 mi n置位 负数
0101 pl n清零 正数或零
0110 vs v置位 溢出
0111 vc v清零 未溢出
1000 hi c置位z清零 无符号数大于
1001 ls c清零z置位 无符号数小于或等于
1010 ge n等于v 带符号数大于或等于
1011 lt n不等于v 带符号数小于
1100 gt z清零且n等于v 带符号数大于
1101 le z置位或n不等于v 带符号数小于或等于
1110 al 忽略 无条件执行

(3. 使用示例

.text   
.global _start   
    
_start:
    MOV r0,#0X3  
    mov r1,#0X1 
    cmp r0,r1  @数值比较
    @根据比较的结果执行不同的指令
    addeq  r2,r1,r0  @如果两个数相等,两数相加,将结果保存至r2中
    subcs r3,r0,r1  @如果r0>=r1,就做减法运算,将结果保存在r3寄存器
    mulcc r4,r0,r1 @如果r0<r1,就做乘法运算,结果保存在r4寄存器中
stop:
    b stop   
.end  

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

7. 跳转指令

(1. 概述

格式:
opcode{cond} label
功能:跳转到指定的标签下

功能码:
1. b :跳转到指定的标签下,返回地址不保存
2.bl:跳转到指定的标签下,返回地址保存至 LR寄存器中

(2. 不保存返回地址

.text   
.global _start   
    
_start:
    MOV r0,#0X3  
    mov r1,#0X1 
    b fun  @跳转到fun标签
    cmp r0,r1  @数值比较
    @根据比较的结果执行不同的指令
    addeq  r2,r1,r0  @如果两个数相等,两数相加,将结果保存至r2中
    subcs r3,r0,r1  @如果r0>=r1,就做减法运算,将结果保存在r3寄存器
    mulcc r4,r0,r1 @如果r0<r1,就做乘法运算,结果保存在r4寄存器中
fun:
    mov r3,#3
    mov r4,#4
stop:
    b stop   
.end  

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

(3. 跳转之前保存返回地址

.text   
.global _start   
_start:
    MOV r0,#0X3  
    mov r1,#0X1 
    bl fun  @跳转到fun标签,返回地址保存至LR寄存器
    cmp r0,r1  @数值比较
    @根据比较的结果执行不同的指令
    addeq  r2,r1,r0  @如果两个数相等,两数相加,将结果保存至r2中
    subcs r3,r0,r1  @如果r0>=r1,就做减法运算,将结果保存在r3寄存器
    mulcc r4,r0,r1 @如果r0<r1,就做乘法运算,结果保存在r4寄存器中
fun:
    mov r3,#3
    mov r4,#4
    mov pc,lr @程序返回
stop:
    b stop   
.end

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发

练习

1. 实现1-100的累加

.text   
.global _start   
_start:

	mov r0,#0 @将r0作为计数器
	mov r1,#0 @将r1作为和

stop:
	add r0,#1		@累计循环次数
	cmp r0,#101 	@比较循环次数
	beq over		@当满足条件时跳转至over处
	addls r1,r1,r0	@当循环次数小于101时累加

    b stop  

over:				@当循环结束跳转到次处

	mov r2,r1		@将r1计算的结果赋值给r2
.end  

Linux 学习记录52(ARM篇),Linux学习记录,linux,学习,arm开发文章来源地址https://www.toymoban.com/news/detail-580792.html

到了这里,关于Linux 学习记录52(ARM篇)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

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

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

相关文章

  • Linux 学习记录56(ARM篇)

    总线是完成传输的一种媒介,总线可以分为系统总线、数据总线和地址总线 系统总线是连接计算机的主要组成部分,它负责传输数据和控制信息。数据总线用于传输数据,而地址总线用于指定数据的存储位置。 串行总线同一时刻,只可以收发一位数据,并且串行总线只有一

    2024年02月15日
    浏览(28)
  • Linux 学习记录54(ARM篇)

    以STM32MP157为例 相关数据手册在文章顶部下载 (1. RCC寄存器 2.5.2 (2. GPIO寄存器 1. 模式配置寄存器 2. 输出模式配置寄存器 3. 速度配置寄存器 4. 上下拉配置寄存器 5. GPIO输出寄存器 (1. RCC寄存器配置 (2. GPIO寄存器配置

    2024年02月16日
    浏览(26)
  • 记录移植Python3到arm开发板linux系统中

    开发板情况 arm板是公司采购的工控机。主要用来 使用python3解析excel表格处理数据。 配置如下: 配置 版本 cpu imx6dl(armv7架构) 操作系统 linux3.10 python版本 2.7 项目情况 项目中最好使用 python3 。可行的有以下几种方式: 方式 优缺点 可行度 重做文件系统 订制程度比较高,后期增

    2024年02月04日
    浏览(40)
  • 嵌入式学习52-ARM1

    知识零散: 1.flash:                                                                                                                                                           nor flash    可被寻地址                                               

    2024年04月14日
    浏览(27)
  • ARM+LINUX嵌入式学习路线

    嵌入式学习是一个循序渐进的过程,如果是希望向嵌入式软件方向发展的话,目前最常见的是嵌入式Linux方向,关注这个方向,大概分3个阶段: 1、嵌入式linux上层应用,包括QT的GUI开发 2、嵌入式linux系统开发 3、嵌入式linux驱动开发 嵌入式目前主要面向的几个操作系统是,

    2024年02月02日
    浏览(51)
  • 【Linux下6818开发板(ARM)】硬件空间挂载

    (꒪ꇴ꒪ ),hello我是 祐言 博客主页:C语言基础,Linux基础,软件配置领域博主🌍 快上🚘,一起学习! 送给读者的一句鸡汤🤔: 集中起来的意志可以击穿顽石! 作者水平很有限,如果发现错误,可在评论区指正,感谢🙏         在嵌入式系统开发中,经常需要使用外部硬件

    2024年02月14日
    浏览(31)
  • linux下arm环境启动脚本/etc/init.d/rcS执行命令失败,踩坑记录

    记一次踩坑记录!!! 接触到一个新的系统,需要在这个系统上跑程序,测试的时候,手动执行脚本和程序都没问题,于是将执行命令写入到linux启动脚本/etc/init.d/rcS这个文件中,然后重启,等待程序起来,但是让我意想不到的是,执行到我加的命令的时候,居然报错,找不

    2024年01月21日
    浏览(31)
  • Rust在linux下交叉编译到arm开发板

    前段时间做了rust交叉编译到arm开发板,如果引入的包有些包含OpenSSL,ring...遇见了很多问题在网上也查阅很多资料,今天抽个时间做个汇总吧。 虚拟机里面安装rust环境,做到交叉编译的时候应该都已经有了,这个地方就不过多说了,网上找一下就有的 首先描述一下我的环境

    2024年02月15日
    浏览(36)
  • [ARM+Linux] 基于全志h616外设开发笔记

    修改用户密码 配置网络 nmcli dev wifi  命令扫描周围WIFI热点   nmcli dev wifi connect  xxx  password xxx 命令 连接WiFi 查看ip地址的指令: ifconfig ip addr show wlan0 SSH登录         这是企业开发调试必用方式,比串口来说不用接线,前提是接入网络并获得板子IP 地址,且系统做了SSH的

    2023年04月21日
    浏览(35)
  • 【嵌入式】Linux开发工具arm-linux-gcc安装及使用

    宿主机 执行编译、链接嵌入式软件的计算机 目标机 运行嵌入式软件的硬件平台 “本地”编译器 用来生成在与编译器本身所在的计算机和操作系统(平台)相同的环境下运行的目标代码,例如 Windows 环境生成 Windows 目标代码。 交叉编译器 用来生成在其它平台上运行的目标代

    2024年01月17日
    浏览(45)

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

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

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

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

二维码1

领取红包

二维码2

领红包