
彭老师的arm第一期笔记
彭老师的arm第一期笔记
看星星的派大星
这个作者很懒,什么都没留下…
展开
专栏收录文章
- 默认排序
- 最新发布
- 最早发布
- 最多阅读
- 最少阅读
-
通过 汇编 分析 结构体
使用 结构体之后, 会节省汇编的 ldr 指令, 结构体 就直接使用 偏移量 来 对变量进行赋值了。注意 : 这里 结构体 依然是一个全局变量。不使用结构体的情况,原创 2024-09-10 17:12:56 · 464 阅读 · 0 评论 -
C与汇编之间的相互调用(29)
注意: 程序通过 r1 -r4 来保存 传递的参数,如果 超过了 4个参数怎么办, 那就 放到栈里面。如果是汇编调用 C语言, 调用的指令就不会 自动的去设置好 R0-R4 的参数了。当调用 C语言函数的时候,就默认 R0 , R4 , 存放的是参数。会自动的将 a 放到r0 里面,将b 放到r1 里面。就默认 超过R5 的参数放到 栈里面 ,从右到左。然后,处理完之后,需要 从栈中去掉相应的 参数。子程序的返回结果 会放到R0 里面。3 然后是 汇编语言调用 C语言。首先是 有了一个汇编的加法函数。原创 2024-09-09 17:04:36 · 422 阅读 · 0 评论 -
内联汇编 (28)
1, %2,%3, 是指 从上往下算, 从左往右算, 1--->10 .这里的constraint 指的就是 寄存器。这个例子 中的 %[op1] 就等于 %1。这里的输出的意思是 , 从汇编到 C语言。输入指的是 从C语言到 汇编语言。r , m , 比较重要。1 首先是基本的格式。命令换行使用 \n\t。2 然后是具体的使用。原创 2024-09-09 16:25:52 · 292 阅读 · 0 评论 -
GNU风格代码编译(27)
Ttext 代表的是,程序的运行地址。-O binary 代表的是 生成二进制文件。-S带表的是 去掉不要重定位信息和符号信息,缩小了文件尺寸。这里的 -O0 代表的是优化的标准, -g,表示增加调试信息, -c , -o 就不用说了。那这里 是不是 说如果就是 .head.text 段的第一条指令呢。这里的 func 单词都是可以替换成具体的函数指针的。3 然后是 uboot ,以及内核的连接脚本的举例。我估计 这里的entry 相当于 标号的意思吧。最主要的是 搞清楚 如何在程序中定义自己的段。原创 2024-09-08 11:55:17 · 603 阅读 · 0 评论 -
5-2 检测内存容量
1 使用的是bios 中断, 每次进行检测都会返回一块 内容。最后的解决方案是 ,自己写了个头文件, 但是 课程的头文件依然保留着, 只是 里面没有内容。myloader.h 是自己写的头文件。这个结构体是 int15 中断需要的。boot_info.h 设置一个结构体用于存放探测到的 内存容量。loader.h 什么也不写, 就是这个头文件出问题的。然后是对于 头文件的包含。接下来是对 顶层 cmake 的修改。types.h 是 一些宏定义。boot_info.h 的内容。types.h 的内容。原创 2024-09-06 23:00:11 · 312 阅读 · 0 评论 -
ARM 伪指令 (26)
ldr 既是一条伪指令 ,也是一条真正的arm 指令。将 val 地址的内容给到 r1 .ldr pc, =32位地址。将val的 地址 给到 r1。这样就可以 实现长跳转。原创 2024-09-06 15:07:10 · 367 阅读 · 0 评论 -
GNU的伪操作 (25)
byte, .short, .long, .quad , .float , 这个是关于 字节的。.string .ascii 是关于字符串的。.arm .thumb, 与 .code 16 , .code32 是同一个意思。.text , .data, .bss . 代表具体的段的名称。这里主要是 对 GNU的 各个伪操作进行 详细的解释。.global 代表这个 变量在其他的文件也可以使用。.set 与 .equ 都是给变量赋值的意思。.extern 代表使用其他文件的变量。原创 2024-09-06 14:31:03 · 527 阅读 · 0 评论 -
汇编伪指令 GNU 风格(24)
这个例子中 space 8 ,0x1 代表的是 填充8个字节,每个字节都是用0x1 来填充。在来看看关于伪操作的内容, 一般是以 . 开头的。标号是不带 . 的, 一般伪指令 是带 . 的。然后是关于 自定义段的操作, 这是比较重要的。定义一个代码段: 这里的x 不知道是什么意思。这里的 BSYM 我不知道是什么意思。这里的.word 代表的是 4个字节。这里的space 不太明白是什么意思。flags 代表的是 读写的约束。这里的重复 不太明白是什么意思。这里的局部标号是需要注意的。原创 2024-09-05 18:52:42 · 574 阅读 · 0 评论 -
软中断 SWI (21)
这里有一个问题, 就是, movs , pc, lr , 之前已经进行了模式的切换,由于每个 模式都有自己的PC,自己的LR,所以这里的 movs 其实没有起到作用,之前状态的 PC以及 LR的值,已经丢失了。这个截图的意思是, 不是硬件会自动的执行 4大步三小步吗, 在 将PC-4 的值, 给到 LR的时候,其实已经完成了模式的切换了,也就是说,这里的LR 已经是特定模式的LR了。这条指令会完成两种功能,一是将 LR 的值, 赋值给PC, 另一种功能就是, 将SPSR的值, 给到CPSR。原创 2024-09-03 18:02:08 · 276 阅读 · 0 评论 -
中断处理流程举例(21)
当中断发生之后,首先是硬件,保存CPSR到SPSR,设置CPSR的 0-4位, 第5位, 关闭中断,保存返回地址,然后跳转到中断地址处,这里由于是中断,所以跳转到 0x18处, -------> 然后是保存现场寄存器,执行中断处理函数------>然后是修正返回地址,然后是跳回去。原创 2024-09-02 14:54:13 · 277 阅读 · 0 评论 -
ARM 异常处理(21)
第二大步: 第一小步,硬件会自动的设置 异常的类型,主要是设置 CPSR的 0-4 位,第二小步, 然后切换到arm 状态下,就是硬件自动设置 CPSR的 第5位 为0 , 第三小步,同时cpu 会自动的关闭CPSR的 中断, 也就是设置I位。这是因为,当中断处理时, PC的值已经更新了,所以PC指向的是, 当前指令,往下数3条指令,硬件会自动的 将PC-4的值,保存到LR中,我们之前已经将LR保存到栈中,现在又从栈中取出了LR的值, 现在还要再-4 才能赋值到PC中。这里就是在 返回地址的修正。原创 2024-09-02 14:38:07 · 650 阅读 · 0 评论 -
ARM 异常(20)
prefetch 异常: 指的是 取址失败的异常,比如取到了 一个 非法的内存地址, 跟DATA异常有点像。swi 异常 -----------------------------> SVC模式。undef 异常 ------------------------>未定义模式。prefetch 异常 ------------->中止模式。irq 异常 ----------------> 中断模式。reset 异常 ------> SVC模式。Fiq 异常 ---------> 快中断模式。原创 2024-08-30 16:14:15 · 358 阅读 · 0 评论 -
ARM 寻址举例(19)
{r1,-r3,r5}, 这里代表的是,将寄存器组的数据,压栈到 sp 指针指向的地方,并且, sp 指针,需要同步向下走。,{r1-r3,r5} , 代表的是,出栈的操作, 出栈的顺序也是, 低地址的内存的值,对应的是低标号的寄存器。, {r1-r3,r5,lr} , 这是在压栈, 这里特别提到了,lr ,这是把函数返回的PC值, 也压栈了。注意: r1,r2,r3,r5 ,在往内存中压栈的时候, 顺序是这样的, 内存中的低地址,存放的是 低标号的寄存器的值。举例: 计算一个数组的所有元素的和。原创 2024-08-29 18:03:07 · 619 阅读 · 0 评论 -
ARM 寻址方式(18)
这条指令的意思是,将寄存器表中的内容,写到R13所指向的内存中,如果加上了!的换,那么再数据写完之后,还要更新一下R13 的值,相当于,再移动指针。首先将 [R 0] 的值 给到R1, 然后将[R0+4] 的值,给到R2, 然后将[R+8] 的值给到R3, 然后将[R0+12] 的值给到R4。就是,以当前PC指针的地址作为基地址,然后将指令中的地址,作为偏移量,然后两者相加,得到一个新的地址。注意,在寄存器组中,不管你写的顺序是什么,他都会,从新 从低到高排列好在进行赋值。就是数据就在 寄存器中。原创 2024-08-28 20:38:31 · 643 阅读 · 0 评论 -
LDR ,STR 指令详解 (17)
如果 目的寄存器是PC的话,而从内存中读到的数据是一块内存的地址,那么这个指令实现的功能与B , BL 的作用是一样的。首先将以R1为内存地址的值 保存到R0中, 然后在 将R1 的值 加上4。对于这个指令一定要与 C语言的 * 操作符联系起来。所以我最好 将 内存的地址 与内存的值, 单独出来。功能: 将存储器的一个32的数据,保存到寄存器中。LDR{条件} 目的寄存器, 但是这条指令还有另外一个作用。arm 的 大致的架构。原创 2024-08-27 16:20:58 · 469 阅读 · 0 评论 -
arm 模式栈初始化
就是通过 CPSR的 后5个 bit 来判断的。那么CPU 怎么区分 处于何种模式呢?然后是 将栈地址 给到PC指针。有多少种模式就有多少种 栈地址。每种模式 都要初始化自己的R13。一共设置了 5种模式 的 SP。首先要 切换到特定的模式,每种模式都有自己的 R13。初始化 栈的一般的步骤,PC 寄存器 是R13。原创 2024-08-27 16:02:05 · 471 阅读 · 0 评论 -
程序状态寄存机 MSR ,MRS (16)
MSR{条件} 程序状态寄存器(CPSR,SPSR), , 操作数。MRS{条件} 通用寄存器, 程序状态寄存器 (CPSR,SPSR)将R0 的值, 写回到 CPSR , 但是只是修改 控制位域。作用: 将寄存器的值, 写回 CPSR 或者 SPSR。7---0 控制域 用c 表示。23--16 状态域 用s表示。31--24 条件域, 用f 表示。15---8 扩展域 用x表示。CPSR的 各个位。原创 2024-08-27 15:42:56 · 312 阅读 · 0 评论 -
数据处理指令 (13)
ADD R0,R2,R3,LSL#1: 将R3做移动1位,与R3 相加然后赋值给R0。SUB R0,R2,R3,LSL#1: 将R3做移动1位,与R3 相减然后赋值给R0。BIC, R0, R0 ,#%1011 , 这是再清除 1,2,3 位置。AND {条件} {S} 目的寄存器,操作数1 , 操作数2.BIC {条件} {S} 目的寄存器,操作数1 , 操作数2.ADD {条件} {S} 目的寄存器,操作数1 , 操作数2.SUB {条件} {S} 目的寄存器,操作数1 , 操作数2.原创 2024-08-26 17:24:26 · 282 阅读 · 0 评论 -
CMP, tst arm 指令 (12)
操作数1 是要操作的数, 操作数2 为掩码,比如操作数2 0x00000010, 两个数 TST 之后,只会留下第 操作数1 的第5位。解释: CMP 用于比较另个寄存器的值,或者是 两个立即数的值,但是并不存储结果,会将 结果的正负值保存到CPSR 的condition 位中。用于将两个寄存器或者 两个立即数的比较, 就是 将两个数 按位与, 这就引出了 位掩码。其结果是 0 或者是1 , 并更新 CPSR 的 Z 位, 我不知道这个位 是什么。CMP,R1,R0 , 将R1-R0。原创 2024-08-26 17:09:47 · 383 阅读 · 0 评论 -
跳转指令 B BL (14)
BL在跳转的时候,会自动的将PC的值 保存到R14中,当返回时, 手动的将R14的值 ,给到PC指针就可以。解释: PC确实是后两个指令,但是将当前指令的下一条指令地址给R14.可以跳转 2的23次方的指令,一个指令是4个字节。所以一共是 32M的大小。最后面为指令跳转的偏移量,所以 BL指令 跳转是有界限的。B label , 就是直接跳转了,不返回。如果超过了 32M, 就要使用 LDR指令。指令的格式 B{条件} 目标地址。COND : 不用解释了。这就是 带条件的跳转了。L : 是BL还是B。原创 2024-08-26 16:54:14 · 206 阅读 · 0 评论 -
arm 指令移位操作(11)
向右移位后,左面填充 第31位的值 ,如果这个数是一个负数的话,那么就用1 来补充。最终移动的是 R2 的数值的低五个bit (共6个bit), 也就是移动了 31位。在移位的过程中,移动的个数也可以是 寄存器,但是只是寄存器的低5个bit有效。带扩展的循环右移: 可以使寄存器也可以是立即数。可以使寄存器也可以是 立即数。可以使寄存器也可以是 立即数。可以使寄存器也可以是 立即数。可以使寄存器也可以是 立即数。可以使寄存器也可以是立即数。LSL : 字母缩写。ASL : 字母缩写。ASR : 字母缩写。原创 2024-08-23 15:03:15 · 443 阅读 · 0 评论 -
mov 指令+ 立即数(10)
就是,一个16进制数, 1的个数不能超过8个, 超过8个了, 肯定是大于255的,如果是没有超过8个的,有可能通过移位的方式来 将 所有的1 都转移到 8个位之内。立即数的范围在 0-255 之前,这个指令的格式有关,立即数,只用8个位来表示,所以最大只有255.而二进制是 1000 0000 0000 0000 0000 0000 0000 0001。然后去掉前面最多的偶数个0 ,去掉后面最大偶数个0。开始移位,首先就两个1 , 有可能凑到 8位以内。mov 指令没什么好说的,接下来看 立即数。原创 2024-08-22 20:26:35 · 376 阅读 · 0 评论 -
协处理器+流水线 (9)
BL指令的第二个周期, L, 是指 将预取的指令+译码的指令全部丢弃,然后,从新预取之前计算的指令,然后,将返回的地址放到 r14 中。IRQ 在 第一个周期的时候,发生,那么 add 指令会执行完,但是 sub 指令就不译码了,开始译码中断指令,并且预取指令。BL指令的第三个周期,A, 的含义不知道,但是已经开始对跳转的指令进行译码了。再第四个周期的时候,开始对预取的指令译码, 但是这里的A,不知道是什么意思。BL 指令的 第一个周期,E , 是指计算出 需要跳转的位置。然后是 ldr 的指令。原创 2024-08-21 14:32:22 · 370 阅读 · 0 评论 -
arm 的寄存器概述(8)
r14(LR ), 这个是比较重要的,主要用于 跳转, 在执行bl 的指令时,会自动的 将下一条指令存放到R14 中,这样,返回时, 直接 ,将LR的值给到PC就可以了。带 三角形的是 这种模式下 独有的寄存器,也就是说,FIQ模式下与 SYstem/user 模式下,虽然都有r8 寄存器,但是不是一个东西。spsr : 备份的程序状态寄存器,当切换状态时,会自动把 cpsr 中的值,保存到spsr .代表的是当前的程序在什么模式下。最前面的 NZCV 为 条件位, 这个也是会用到的。原创 2024-08-19 18:05:22 · 280 阅读 · 0 评论 -
arm 的模式+异常(7)
用户模式: 不能访问硬件资源,但是可以通过系统调用来访问。管理模式: 这个跟系统调用有关,也跟软中断,swi 有关。4 undef , 流水线中执行 未知的指令时的异常。7 data, 这指的是 访问非法的内存单元的异常。6 prefech , 这表示无法预取指令的异常。一般中断+快速中断模式,这个可以访问硬件资源。monitor 模式,不解释,用不到,也不懂。5 swi , 这是软中断的异常。系统模式: 操作系统运行的模式。1 reset ,这也算异常。3 操作系统的8种模式。未定义模式,不解释。原创 2024-08-19 18:05:04 · 182 阅读 · 0 评论