嵌入式微处理器重点学习(一)

LDMIA R0, {R1, R2, R3, R4}; 和LDMIA R0!, {R1, R2, R3, R4}; 有什么区别

在 ARM 架构的指令集中,LDMIA 是一条加载多个寄存器的指令,其含义为 Load Multiple Increment After,即从内存中加载多个寄存器的值,并且在加载后内存地址递增。
LDMIA R0, {R1, R2, R3, R4}: 这条指令意味着从 R0 指向的内存地址开始,依次将数据加载到 R1, R2, R3, R4,加载完成后,R0 的值不会改变。
LDMIA R0!, {R1, R2, R3, R4}: 结尾的 ! 表示更新基址寄存器。这条指令同样从 R0 指向的内存地址开始,依次将数据加载到 R1, R2, R3, R4,与上一条指令不同的是,执行完这条指令后,R0 的值会更新为最后一个被加载的地址加上 4(即最后一个数据的下一个地址),实质上反映了内存地址的递增。
本质区别在于第二条指令中使用了 !,表示在加载数据到寄存器后,会更新 R0 寄存器的值为新的地址,即指向这一系列操作完成后的下一个内存位置。这种机制通常用于访问连续的内存块,如数组或结构体,且需要在访问过程中更新基址寄存器以指向下一个数据块。

传参数目小于等于4是,直接按顺序用R0, R1, R2, R3传参,超过这个数目就要用栈了,如何用栈传参?a+b+c+d+e用arm指令

在ARM指令集中,当需要传递的参数数量超过4个时,通常会利用堆栈(stack)进行参数传递。以下是一个使用栈传递五个参数(a, b, c, d, e)并计算它们之和的ARM汇编示例:
assembly

.text
.global _start

_start:
    // 假设a, b, c, d, e的值分别为1, 2, 3, 4, 5
    MOV R0, #1  // a
    MOV R1, #2  // b
    MOV R2, #3  // c
    MOV R3, #4  // d
    
    // 将第5个参数e压入栈中
    MOV R4, #5  // e
    PUSH {R4}   // 将e的值压栈
    
    // 调用函数计算a+b+c+d+e
    BL sum_five_numbers
    
    // 结果将在R0中,此处可以添加代码以使用结果
    
    // 终止程序 (在某些环境下有效)
    MOV R7, #1
    SWI 0

// 函数:计算五个数的和
// 参数:R0=a, R1=b, R2=c, R3=d, 栈顶=e
// 返回值:R0=结果
sum_five_numbers:
    // 将R0-R3的值相加,结果存回R0
    ADD R0, R0, R1
    ADD R0, R0, R2
    ADD R0, R0, R3
    
    // 从栈中弹出第5个参数e到R4,并将其加到R0的结果上
    POP {R4}
    ADD R0, R0, R4
    
    // 返回
    BX LR

这个示例展示了如何在ARM汇编语言中通过堆栈传递超过4个的函数参数。首先,前4个参数直接通过寄存器 R0 到 R3 传递,接着额外的参数(这里是第5个参数)通过将值压入堆栈的方式传递。在函数 sum_five_numbers 内部,使用 POP 指令从堆栈中弹出第5个参数,并计算所有参数的总和,最后通过 R0 返回计算结果。

优化等级

arm-none-eabi-gcc -S test.c –O0
arm-none-eabi-gcc -S test.c –O1
发现产生的汇编文件长度变短了
假如现在要操作一个外设寄存器(GPIO),它的地址是
rGPFCON = 0x56000050
我们的每一次读写都必须确确实实地作用在0x56000050这个地址上,而当我们使用了较高的优化等级如-O3时,编译器可能会把对外设寄存器的访问优化掉。
为了解决这类问题,可以使用volatile关键字修饰寄存器地址

#pragma omp parallel for

#pragma omp parallel for 是一种 OpenMP 编译制导语句,用于指示编译器将接下来的 for 循环并行化执行。这意味着循环的迭代将在不同的线程中并行运行,以提高程序的执行效率。这条指令将循环的迭代分配给多个线程,根据系统的可用核心数量和 OpenMP 的调度机制,自动分配循环的迭代给这些线程执行。

#include <stdio.h>
#include <omp.h>
#define N 100

int main() {
    int i, sum = 0;
    int a[N];

    // 初始化数组
    for(i = 0; i < N; i++) {
        a[i] = i + 1;
    }

    #pragma omp parallel for reduction(+:sum)
    for(i = 0; i < N; i++) {
        sum += a[i];
    }

    printf("Total Sum = %d\n", sum);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值