• 用ARM进行汇编语言编程(1)介绍与寻址模式


    简介

    汇编语言是计算机的低级编程语言,它是最接近机器语言的语言,arm是一种用于各种不同应用程序的编程语言,通过arm汇编语言,程序员可以在较低的层次上编程与硬件交互的代码

    ARM 编程模拟器

    ARM 编程模拟器网站地址:

    https://cpulator.01xz.net/?sys=arm-de1soc
    
    • 1

    进入这个网站

    在这里插入图片描述

    这个地方是显示寄存器的位置

    在这里插入图片描述

    寄存器是内存中非常靠近cpu的区域,因此可以快速访问它们,但是在这些寄存器里面能存储的东西非常有限
    这个地方显示内存里的值

    在这里插入图片描述

    sp寄存器会告诉我们堆栈上下一个可以用内存的地址,现在sp里的值全是0,所以我们下一个可用的内存地址的值在这里

    在这里插入图片描述
    在这里插入图片描述

    现在我选中的地址为0,在它旁边的地址为4,以此类推

    在这里插入图片描述

    现在选中的这个位置为16,以此类推

    在这里插入图片描述

    LR寄存器是我们的链接寄存器,如果使用过高级语言就会知道,当你有一个函数时,函数就会有一个返回值,而这个值会让我们回到调用函数的位置,这就是链接寄存器的作用

    在这里插入图片描述

    PC是我们的程序计数器,它的作用是跟踪要执行的下一条指令的位置

    在这里插入图片描述

    第一个程序

    在我们程序的起点,模拟器会自动放入两行开始代码,告诉程序的起点在哪,如果在模拟器之外的地方编程,需要自己手动写入

    在这里插入图片描述

    我们将在_start:下面写入代码,_start:被称为标签,标签和高级语言中函数差不多,这是一种能划分代码段的方法
    我们先来写一个简单的代码,代码的作用是将一些数据移动到寄存器里,然后在将一些数据移动到另一个寄存器里,我们看看数据是如何移动到寄存器里的

    mov r0,#30                   //将30移动到寄存器0中
    mov r7,#1                    //将1移动到寄存器7中
    SWI 0                        //中断程序
    
    • 1
    • 2
    • 3

    然后按下f5运行代码

    在这里插入图片描述

    现在这个界面为反汇编界面,然后按下f2,一步一步执行代码

    在这里插入图片描述

    可以看到,r0寄存器里的值已经改变了,1e与十进制的30相同,
    在这里可以将寄存器十六进制的值转换为十进制

    在这里插入图片描述
    在这里插入图片描述

    寻址类型

    寻址类型的定义是在程序的内存位置上可以通过多种方式从内存中存储和检索数据,在上面我们就运用了一种寻址类型,叫做立即寻址

    mov r0,#30                   //将30移动到寄存器0中
    mov r7,#1                    //将1移动到寄存器7中
    
    • 1
    • 2

    取一个值,将其直接放入一个寄存器,这种类型就叫做立即寻址
    我们还可以将一个寄存器里的值,放入另一个寄存器中

    mov r1,#1     //将1放入寄存器1中
    mov r2,r1    //将r1寄存器里的值放入r2寄存器中
    
    • 1
    • 2

    我们还可以定义一个数据段在里面存放数据,之后需要调用时可以直接调用这个数据段

    .data    //data段,用于存放数据
    
    • 1

    之后我们可以随意在里面定义变量

    在这里插入图片描述

    .global _start
    _start:
    	
    .data
    baimao:   //定义的变量名
    	.word 1,2,-3,4,5,-6,7,8,-9,10   //.word:告诉程序每一个值都是word类型,大小为32位,用于存放数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    现在我需要调用这个变量在内存中的位置,只需要在baimao里查找第一个条目就好了,它会从第一个开始依次出现在内存中

    .global _start
    _start:
    	ldr r0,=baimao     //ldr:将data段里baimao中的数据加载到r0寄存器中
    .data
    baimao:   //定义的变量名
    	.word 1,2,-3,4,5,-6,7,8,-9,10   //.word:告诉程序每一个值都是word类型,大小为32位,用于存放数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    在这里插入图片描述

    然后按f5运行,进入汇编页面

    在这里插入图片描述

    然后在右下角设置位十进制显示

    在这里插入图片描述

    ctrl+m进入内存页面,就能以十进制显示我们的数据

    在这里插入图片描述

    我们还可以用另一个寻址模式来演示一下从该位置检索值

    .global _start
    _start:
    	ldr r0,=baimao     //ldr:将data段里baimao中的数据加载到r0寄存器中
    	ldr r1,[r0]   //汇编程序寻找r0寄存器地址中的值,移动到r1寄存器里
    .data
    baimao:   //定义的变量名
    	.word 1,2,-3,4,5,-6,7,8,-9,10   //.word:告诉程序每一个值都是word类型,大小为32位,用于存放数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    按f5汇编后,进入汇编页面

    在这里插入图片描述

    按f2执行程序后可以看到,r0寄存器里的值为16

    在这里插入图片描述

    进入内存,可以发现确实存在一个16的值,后面的那个0为方括号的值

    在这里插入图片描述

    继续按下f2后,r1寄存器里的值就是我们之前定义的值了

    在这里插入图片描述

    r0寄存器里的值就是告诉程序从哪个内存地址里获取值,这里是16,所以在内存里也看到了16,紧挨着的就是我们定义的一些值

    这里我用python来演示一下,可以更好的理解

    .global _start
    _start:
    	ldr r0,=baimao     //ldr:将data段里baimao中的数据加载到r0寄存器中
    	ldr r1,[r0]   //汇编程序寻找r0寄存器地址中的值,移动到r1寄存器里
    .data
    baimao:   //定义的变量名
    	.word 1,2,-3,4,5,-6,7,8,-9,10   //.word:告诉程序每一个值都是word类型,大小为32位,用于存放数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    //上面那个汇编程序
    
    baimao = [1,2,-3,4,5,-6,7,8,-9,10]
    baimao[i]    //i就相当于r0寄存器的作用
    
    • 1
    • 2
    • 3
    • 4

    还有其他方法可以调用变量里的值,比如说,我只需要2以后的这些值,该怎么办呢
    这里我们可以使用偏移量来达到我们想要的值

    .global _start
    _start:
    	ldr r0,=baimao     //ldr:将data段里baimao中的数据加载到r0寄存器中
    	ldr r1,[r0]   //汇编程序寻找r0寄存器地址中的值,移动到r1寄存器里
    	ldr r2,[r0,#4]   //偏移4字节,移动到r1寄存器里
    .data
    baimao:   //定义的变量名
    	.word 1,2,-3,4,5,-6,7,8,-9,10   //.word:告诉程序每一个值都是word类型,大小为32位,用于存放数据
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里我用python来演示一下,可以更好的理解

    //上面那个汇编程序
    
    baimao = [1,2,-3,4,5,-6,7,8,-9,10]
    baimao[i+1]    //+1就相当于偏移量
    
    • 1
    • 2
    • 3
    • 4

    因为在内存中下一个值的位置是四个字节,所以这里偏移4位

    在这里插入图片描述

    运行程序,可以看到r2寄存器里的值变成了2

    在这里插入图片描述

    在这里插入图片描述

    总结

    这是我学习的笔记,有什么错误和不懂的地方欢迎来私信我,或者加我qq

  • 相关阅读:
    【初识JavaSe语法笔记起章】——标识符、关键字、字面常量、数据类型、类型转换与提升、字符串类型
    思维导图:MindManager Professional 22.0 Crack
    5G通信与蜂窝模组之间的关系
    Theory behind GAN
    .NET 面试题集锦
    List.of()的坑——不能够序列化
    Linux基本命令
    STC15/8单片机特有的PWM寄存器和普通定时器实现PWM输出
    RabbitMQ实现秒杀场景示例
    现代 CSS 解决方案:文字颜色自动适配背景色!
  • 原文地址:https://blog.csdn.net/qq_45894840/article/details/124556356