将 GCC 内联汇编与采用立即值的指令结合使用

2024-04-17

问题

我正在为 ARM Cortex-M3 处理器开发定制操作系统。为了与我的内核交互,用户线程必须生成 SuperVisor Call (SVC) 指令(以前称为 SWI,用于软件中断)。该指令在ARM ARM中的定义是:

这意味着该指令需要即时参数,而不是寄存器值。

这使得我很难以可读的方式构建我的界面。它需要如下代码:

asm volatile( "svc #0");

当我更喜欢类似的东西时

svc(SVC_YIELD);

然而,我无法构造这个函数,因为 SVC 指令需要一个立即参数,而当值通过寄存器传入时我无法提供该参数。

内核:

对于后台,svc指令在内核中解码如下

#define SVC_YIELD   0
// Other SVC codes

// Called by the SVC interrupt handler (not shown)
void handleSVC(char code)
{
  switch (code) {

    case SVC_YIELD:
      svc_yield();
      break;
    // Other cases follow

这个案例陈述正在迅速失控,但我认为没有办法解决这个问题。欢迎任何建议。

我尝试过的

带有寄存器参数的 SVC

我最初考虑

__attribute__((naked)) svc(char code)
{
    asm volatile ("scv r0"); 
}

但这当然不起作用,因为 SVC 需要寄存器参数。

暴力破解

解决问题的暴力尝试如下:

void svc(char code)
  switch (code) {
    case 0:
      asm volatile("svc #0");
      break;
    case 1:
      asm volatile("svc #1");
      break;
    /* 253 cases omitted */
    case 255:
      asm volatile("svc #255");
      break;
  }
}

但这有一种令人讨厌的代码味道。当然,这可以做得更好。

动态生成指令编码

最后的尝试是在 RAM 中生成指令(其余代码从只读闪存运行),然后运行它:

void svc(char code)
{
  asm volatile (
      "orr r0, 0xDF00  \n\t" // Bitwise-OR the code with the SVC encoding
      "push {r1, r0}   \n\t" // Store the instruction to RAM (on the stack)
      "mov r0, sp      \n\t" // Copy the stack pointer to an ordinary register
      "add r0, #1      \n\t" // Add 1 to the address to specify THUMB mode
      "bx r0           \n\t" // Branch to newly created instruction
      "pop {r1, r0}    \n\t" // Restore the stack
      "bx lr           \n\t" // Return to caller
      );
}

但这感觉也不对劲。而且,它不起作用 - 我在这里做错了一些事情;也许我的指令没有正确对齐,或者我没有设置处理器以允许在此位置从 RAM 运行代码。

我应该怎么办?

我必须努力研究最后一个选择。但仍然感觉我应该能够做类似的事情:

__attribute__((naked)) svc(char code)
{
    asm volatile ("scv %1"
         : /* No outputs */
         : "i" (code)    // Imaginary directive specifying an immediate argument
                         // as opposed to conventional "r"
          ); 
}

但我在文档中没有找到任何这样的选项,并且我无法解释如何实现这样的功能,所以它可能不存在。我该怎么做?


您想要使用约束来强制将操作数分配为 8 位立即数。对于ARM来说,这是约束I。所以你要

#define SVC(code) asm volatile ("svc %0" : : "I" (code) )

请参阅 GCC 文档以获取所有限制的摘要 - 您需要查看特定于处理器的注释以了解特定平台的限制。在某些情况下,您可能需要查看.mdgcc 源代码中的体系结构(机器描述)文件以获取完整信息。

还有一些很好的特定于 ARM 的 gcc 文档here http://www.ethernut.de/en/documents/arm-inline-asm.html。在“输入和输出操作数”标题下的几页中,它提供了所有 ARM 约束的表格

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

将 GCC 内联汇编与采用立即值的指令结合使用 的相关文章

随机推荐

  • 安排行动断言替代方案

    一般问题是单元测试是否有 AAA 的替代模式 如果是的话 看到一些例子并了解它们的优点和缺点将会非常有趣 作为 AAA 测试的最简单示例 在 C 中 为了简单起见 使用 var Arranging var annualSalary 1200
  • ListViewItem 覆盖默认样式中断网格视图

    我想知道是否有人遇到过这种情况 基本上我想做的是覆盖默认的列表视图项以自定义所选的背景 前景 我一切顺利 问题是 我注意到在我实现了网格视图的列表视图上 列被破坏了 我不确定会发生什么来打破这个 我覆盖默认样式的方法是使用混合通过编辑模板副
  • 使用 Formik 反应验证最大范围

    我正在尝试使用 React 和 Formik 进行验证 我想要实现最大数字仅为 2 最大范围应仅为 12 expiryMonth yup string required Select month max 2 Invalid month fo
  • ggplot2 facet_wrap 在每个方面绘制点、段、文本

    这与已发布的问题相同here https stackoverflow com questions 11889625 annotating text on individual facet in ggplot2 and here https
  • 调用always_inline‘_mm_mullo_epi32’时内联失败:目标特定选项不匹配

    我正在尝试使用 cmake 编译 C 程序 该程序使用 SIMD 内在函数 当我尝试编译它时 出现两个错误 usr lib gcc x86 64 linux gnu 5 include smmintrin h 326 1 错误 调用alwa
  • userprincipal.findbyidentity 发生操作错误

    好吧 我有责任将具有多个应用程序的网站迁移到另一台服务器 迁移进展顺利 所有应用程序都正常运行 然而 该新服务器的性能低于标准 完全是另一回事 我们决定再次迁移它 这次一切都运行良好 除了一个应用程序 它在第一台和第二台 IIS 服务器上运
  • Protractor 中的全局 beforeEach 和 afterEach

    在每个规范中我都有beforeEach and afterEach声明 是否可以以某种方式全局添加它以避免规范之间的代码重复 目的beforeEach and afterEach 函数是添加一个重复代码块 每次开始或完成执行每个规范时都需要
  • HTML5 Canvas:绘制完成时获取事件

    我正在将图像绘制到画布元素 然后我就有了依赖于这个过程来完成的代码 我的代码如下所示 var myContext myCanvasElement getContext 2d myImg new Image myImg onload func
  • 什么是位掩码?

    我对 C 编程相当陌生 并且遇到了位掩码 位掩码的一般概念和作用是什么 非常感谢例子 掩码定义要保留哪些位以及要清除哪些位 屏蔽是将屏蔽应用于值的行为 这是通过执行以下操作来完成的 按位与运算以提取值中的位子集 按位或运算以设置值中的位子集
  • 大数据请求体为空

    我在 post 方法的正文中发送大量文本 我使用 Postman 来测试这一点 但是它工作正常 我可以像这样读取请求正文 String text request body asText 但是当我尝试在正文中发送大量数据时 我得到的文本为空
  • Websphere 7集群部署

    我们有一个 J2EE 应用程序作为 EAR 文件 部署在 WAS 7 中 为了使应用程序可用性尽可能高 需要部署在 3 个集群中 我们有一个 Quartz Scheduler 类 其工作是每天凌晨 2 00 将数据从一个数据库上传到另一个数
  • MobX-State-Tree 流程中的类型化 Yield 表达式

    在 MobX state tree MST 中执行异步操作的推荐方法是使用flow https mobx state tree js org concepts async actions 它接受一个生成器函数作为第一个参数 其中每个承诺都应
  • 在 Docker 容器接口上应用 NetEM WAN 延迟

    我想对 docker 容器的出口流量应用 NetEm 延迟 通常 我运行 sbin tc qdisc add dev INTERFACE root netem delay DELAY ms 问题是我不知道容器连接到的接口 例如 我正在运行以
  • 本地化 JavaAnpr 以获取本地车牌

    我正在与JavaAnpr http javaanpr sourceforge net 自动识别车牌 虽然它适用于欧洲车牌 但不适用于我的国家 例如 如何编辑资源文件和语法 XML 以支持其他国家 地区 michel layyous 这是作者
  • 从二元高斯分布生成均值

    我正在阅读统计学习要素ESLII http www stat stanford edu tibs ElemStatLearn 在第二章中 他们用高斯混合数据集来说明一些学习算法 为了生成该数据集 他们首先从二元高斯分布 N 1 0 I 生成
  • 如何在 Windows PowerShell 中使用 .bat 文件更改当前目录?

    我正在学习 Windows PowerShell 并且正在努力完成非常基本的任务 如何创建 bat 文件来更改当前目录 简单的 bat 文件cd mydir里面用得很好cmd exe 但它在 PowerShell 中不起作用 PS C Us
  • 将条目插入到 crontab 中,除非它已经存在(如果可能的话作为单行)[重复]

    这个问题在这里已经有答案了 将条目插入 etc crontab 的首选方法是什么 除非它存在 最好使用单行 这是我希望放入 etc crontab 中的示例条目 除非它已经存在于其中 1 some user python mount sha
  • 在 .NET core 2.0 中创建迁移步骤时,将“IDesignTimeDbContextFactory”的实现添加到项目错误中

    我有一个 NET core 1 0 web 应用程序运行良好 我必须升级到 NET Core 2 0 我还必须为我的 SQLite 数据库添加迁移步骤 如果我启动这个命令 添加迁移 MyMigrationStepName 我收到此错误 无法
  • JMS 会话寿命长。保持 JMS 连接/JMS 会话总是打开是一种不好的做法吗?

    保持 JMS 连接 会话 消费者始终打开是一种不好的做法吗 代码草案示例 app startup code ConnectionFactory cf ConnectionFactory jndiContext lookup CF JNDI
  • 将 GCC 内联汇编与采用立即值的指令结合使用

    问题 我正在为 ARM Cortex M3 处理器开发定制操作系统 为了与我的内核交互 用户线程必须生成 SuperVisor Call SVC 指令 以前称为 SWI 用于软件中断 该指令在ARM ARM中的定义是 这意味着该指令需要即时