• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录

SOC/IP验证工程师

  • 博客园
  • 联系
  • 订阅
  • 管理

公告

View Post

ARMv8-R汇编内联语法详解

在 ARMv8-R 架构中使用 __asm__ __volatile__ 是 GCC 编译器提供的内联汇编语法,用于在 C/C++ 代码中嵌入汇编指令。以下是详细用法说明和示例:


基本语法结构

__asm__ __volatile__ (
    "汇编指令"         // 指令部分
    : "输出操作数列表"   // 输出操作数(可选)
    : "输入操作数列表"   // 输入操作数(可选)
    : "破坏列表"        // 破坏寄存器列表(可选)
);

关键组成部分解析

  1. __volatile__
    禁止编译器优化此段汇编,确保指令按原样执行(对硬件操作至关重要)。

  2. 汇编指令

    • 用双引号包裹,多条指令用 \n\t 分隔。
    • 使用 %0, %1 等占位符引用操作数。
  3. 操作数约束

    • 输出操作数:"=约束"(变量)(= 表示只写)。
    • 输入操作数:"约束"(变量)。
    • 常用约束:
      • r:通用寄存器。
      • m:内存操作数。
      • I:立即数。
  4. 破坏列表(Clobber List)
    声明可能被修改的寄存器或内存:

    • "memory":表示内存被修改。
    • "cc":表示条件标志被修改。
    • 寄存器名:如 "r0", "r1"。

ARMv8-R 典型使用场景示例

示例 1:读取系统寄存器

uint64_t read_cntvct(void) {
    uint64_t val;
    __asm__ __volatile__(
        "mrs %0, cntvct_el0"  // 读取 CNTVCT_EL0 到 val
        : "=r" (val)          // 输出:val 使用通用寄存器
    );
    return val;
}

示例 2:写入系统寄存器

void set_daif(uint64_t value) {
    __asm__ __volatile__(
        "msr daif, %0"        // 将 value 写入 DAIF
        :                     // 无输出
        : "r" (value)         // 输入:value 存入寄存器
        : "cc"                // 破坏:条件标志寄存器
    );
}

示例 3:内存屏障指令

void data_barrier(void) {
    __asm__ __volatile__(
        "dsb sy"              // 数据同步屏障
        ::: "memory"          // 破坏:内存(防止编译器乱序)
    );
}

示例 4:原子操作

void atomic_increment(uint32_t *addr) {
    __asm__ __volatile__(
        "ldrex r1, [%0]\n"   // 原子加载
        "add r1, r1, #1\n"    // 自增
        "strex r0, r1, [%0]"  // 原子存储
        :                     // 无输出
        : "r" (addr)          // 输入:addr 指针
        : "r0", "r1", "cc", "memory"  // 破坏:寄存器 r0/r1、条件标志、内存
    );
}

注意事项

  1. 寄存器约束
    ARMv8-R 有 32 个 64 位通用寄存器(x0-x30),32 位时用 w0-w30。明确指定寄存器需用 asm("mov x0, #1") 直接操作。

  2. 内存屏障
    在操作硬件寄存器前,使用 dsb/isb 确保顺序性:

    __asm__ __volatile__("dsb sy\n\tisb sy" ::: "memory");
    
  3. 避免冗余破坏声明
    只声明实际被修改的寄存器,过度声明会降低性能。

  4. 检查编译器支持
    确保编译器支持 ARMv8-R(如 GCC 的 -march=armv8-r 选项)。


错误用法示例

// 错误:未声明破坏的寄存器
__asm__("mov r0, #1"); // 可能破坏 r0 导致程序错误

// 正确:显式声明破坏
__asm__ __volatile__(
    "mov r0, #1"
    : : : "r0"  // 声明 r0 被修改
);

通过合理使用 __asm__ __volatile__,可直接操作 ARMv8-R 的底层硬件资源(如系统寄存器、中断控制等),适用于实时系统、固件开发等场景。

posted on 2025-08-01 22:07  SOC验证工程师  阅读(27)  评论(0)    收藏  举报

刷新页面返回顶部
 
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3