热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

在没有编译器的情况下创建C函数会生成序言/结尾和RET指令?

如何解决《在没有编译器的情况下创建C函数会生成序言/结尾和RET指令?》经验,为你挑选了1个好方法。

考虑以下功能:

void foo(){
    //do something
}

在组装时,它看起来像这样(不准确):

push something

;do stuff

pop something
ret

但是我不想要这个生成的代码(RETPUSHPOP ...)。我只想在代码块上加上标签,所以我必须返回自己:

void bar(){
    //do something
    asm("iret") //i want to use this function as a ISR
}

并在组装中看起来像这样:

; do something
iret

没有PUSHPOPRET。是否有任何预处理器指令或关键字可以帮助我完成此任务?

我正在Windows下使用GCCNASM,并且试图生成自己的中断服务例程(ISR)。



1> Michael Petc..:

尚不清楚您要完成什么。似乎您想要一个中断处理程序,该中断处理程序iret默认情况下没有其他推送和弹出操作。


海湾合作委员会

使用GCC(不使用NASM)可能是这样的:

/* Make C extern declarations of the ISR entry points */    
extern void isr_test1(void);
extern void isr_test2(void);

/* Define a do nothing ISR stub */
__asm__(".global isr_test1\n"
        "isr_test1:\n\t"
        /* Other stuff here */
        "iret");    

/* Define an ISR stub that makes a call to a C function */
__asm__(".global isr_test2\n"
        "isr_test2:\n\t"
        "cld\n\t"                    /* Set direction flag forward for C functions */
        "pusha\n\t"                  /* Save all the registers */
        /* Other stuff here */
        "call isr_test2_handler\n\t"
        "popa\n\t"                   /* Restore all the registers */
        "iret");

void isr_test2_handler(void)
{
    return;
}

GCC中的基本__asm__语句可以放在函数之外。我们为我们的中断服务程序(ISR)定义标签,并使它们在外部可见(您可能不需要全局可见性,但无论如何我都会显示出来)。.globl

我创建了几个示例中断服务例程。一个只做一个iret,而另一个做一个对C处理程序的函数调用。我们保存所有寄存器,然后将其还原。C函数要求将方向标志设置为正向,因此在调用C函数之前需要CLD。此示例代码适用于32位目标。64位可以通过保存寄存器单独而不是使用来完成PUSHAPOPA

注意:如果使用GCC在Windows函数名称组装块可能会需要有预先考虑_(下划线)。它看起来像:

/* Make C extern declarations of the ISR entry points */    
extern void isr_test1(void);
extern void isr_test2(void);

/* Define a do nothing ISR stub */
__asm__(".global _isr_test1\n"
        "_isr_test1:\n\t"
        /* Other stuff here */
        "iret");    

/* Define an ISR stub that makes a call to a C function */
__asm__(".global _isr_test2\n"
        "_isr_test2:\n\t"
        "cld\n\t"                    /* Set direction flag forward for C functions */
        "pusha\n\t"                  /* Save all the registers */
        /* Other stuff here */
        "call _isr_test2_handler\n\t"
        "popa\n\t"                   /* Restore all the registers */
        "iret");

void isr_test2_handler(void)
{
    return;
}

MSVC / MSVC ++

Microsoft的C / C ++编译器支持函数的属性。他们将此属性描述为:

裸存储类属性是Microsoft对C语言的特定扩展。对于使用裸存储类属性声明的函数,编译器将生成不含序言和结语代码的代码。您可以使用此功能通过内联汇编代码编写自己的序言/结尾代码序列。裸函数在编写虚拟设备驱动程序时特别有用。

一个示例中断服务程序可以这样完成:

__declspec(naked) int isr_test(void)
{
    /* Function body */
    __asm { iret };
}

您将需要处理保存和恢复寄存器的问题,以与上述GCC示例类似的方式自行设置方向标志。


GCC 7.x +在x86 / x86-64目标上引入了中断属性

现在,您可以在GCC 7.0+上使用__attribute__((interrupt))函数了。仅在x86和x86-64目标上最近才支持此属性:

打断

使用此属性指示指定的函数是中断处理程序还是异常处理程序(取决于传递给该函数的参数,将进一步说明)。当存在此属性时,编译器会生成适合在中断处理程序中使用的函数进入和退出序列。IRET指令而不是RET指令用于从中断处理程序中返回。除由IRET指令恢复的EFLAGS寄存器外,所有寄存器均由编译器保留。由于GCC不会保留MPX,SSE,MMX或x87状态,因此应使用GCC选项-mgeneral-regs-only来编译中断和异常处理程序。

该方法仍然存在缺陷。如果您希望C代码访问中断时出现的寄存器内容,那么目前尚无可靠的方法来使用此机制。如果您正在编写软件中断并需要访问寄存器以确定要执行的操作(即:int 0x80在Linux上),这将很方便。另一个示例是允许中断将所有寄存器的内容转储到显示器以进行调试。


推荐阅读
  • 2020年9月15日,Oracle正式发布了最新的JDK 15版本。本次更新带来了许多新特性,包括隐藏类、EdDSA签名算法、模式匹配、记录类、封闭类和文本块等。 ... [详细]
  • 【妙】bug称它为数组越界的妙用
    1、聊一聊首先跟大家推荐一首非常温柔的歌曲,跑步的常听。本文主要把自己对C语言中柔性数组、零数组等等的理解分享给大家,并聊聊如何构建一种统一化的学习思想 ... [详细]
  • malloc 是 C 语言中的一个标准库函数,全称为 memory allocation,即动态内存分配。它用于在程序运行时申请一块指定大小的连续内存区域,并返回该区域的起始地址。当无法预先确定内存的具体位置时,可以通过 malloc 动态分配内存。 ... [详细]
  • 包含phppdoerrorcode的词条 ... [详细]
  • 高端存储技术演进与趋势
    本文探讨了高端存储技术的发展趋势,包括松耦合架构、虚拟化、高性能、高安全性和智能化等方面。同时,分析了全闪存阵列和中端存储集群对高端存储市场的冲击,以及高端存储在不同应用场景中的发展趋势。 ... [详细]
  • 本文详细介绍了Java反射机制的基本概念、获取Class对象的方法、反射的主要功能及其在实际开发中的应用。通过具体示例,帮助读者更好地理解和使用Java反射。 ... [详细]
  • 本文回顾了作者初次接触Unicode编码时的经历,并详细探讨了ASCII、ANSI、GB2312、UNICODE以及UTF-8和UTF-16编码的区别和应用场景。通过实例分析,帮助读者更好地理解和使用这些编码。 ... [详细]
  • 字符串学习时间:1.5W(“W”周,下同)知识点checkliststrlen()函数的返回值是什么类型的?字 ... [详细]
  • 单片机入门指南:基础理论与实践
    本文介绍了单片机的基础知识及其应用。单片机是一种将微处理器(类似于CPU)、存储器(类似硬盘和内存)以及多种输入输出接口集成在一块硅片上的微型计算机系统。通过详细解析其内部结构和功能,帮助初学者快速掌握单片机的基本原理和实际操作方法。 ... [详细]
  • 深入解析C语言中结构体的内存对齐机制及其优化方法
    为了提高CPU访问效率,C语言中的结构体成员在内存中遵循特定的对齐规则。本文详细解析了这些对齐机制,并探讨了如何通过合理的布局和编译器选项来优化结构体的内存使用,从而提升程序性能。 ... [详细]
  • 本文详细介绍了批处理技术的基本概念及其在实际应用中的重要性。首先,对简单的批处理内部命令进行了概述,重点讲解了Echo命令的功能,包括如何打开或关闭回显功能以及显示消息。如果没有指定任何参数,Echo命令会显示当前的回显设置。此外,文章还探讨了批处理技术在自动化任务执行、系统管理等领域的广泛应用,为读者提供了丰富的实践案例和技术指导。 ... [详细]
  • Python默认字符解析:深入理解Python中的字符串处理
    在Python中,字符串是编程中最基本且常用的数据类型之一。尽管许多初学者是从C语言开始接触字符串,通常通过经典的“Hello, World!”程序入门,但Python对字符串的处理方式更为灵活和强大。本文将深入探讨Python中的字符串处理机制,包括字符串的创建、操作、格式化以及编码解码等方面,帮助读者全面理解Python字符串的特性和应用。 ... [详细]
  • html显示屏幕中心1,HTML中常见的长度单位
    8种机械键盘轴体对比本人程序员,要买一个写代码的键盘,请问红轴和茶轴怎么选?THML中常见的8种长度1、常见的单位px:像素 ... [详细]
  • 在《Cocos2d-x学习笔记:基础概念解析与内存管理机制深入探讨》中,详细介绍了Cocos2d-x的基础概念,并深入分析了其内存管理机制。特别是针对Boost库引入的智能指针管理方法进行了详细的讲解,例如在处理鱼的运动过程中,可以通过编写自定义函数来动态计算角度变化,利用CallFunc回调机制实现高效的游戏逻辑控制。此外,文章还探讨了如何通过智能指针优化资源管理和避免内存泄漏,为开发者提供了实用的编程技巧和最佳实践。 ... [详细]
  • 本文目录一览:1、\mysybase.dump对数据库正常使用有影响吗 ... [详细]
author-avatar
好人森森_195
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有