热门标签 | 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上),这将很方便。另一个示例是允许中断将所有寄存器的内容转储到显示器以进行调试。


推荐阅读
  • linux进阶50——无锁CAS
    1.概念比较并交换(compareandswap,CAS),是原⼦操作的⼀种,可⽤于在多线程编程中实现不被打断的数据交换操作࿰ ... [详细]
  • 恶意软件分析的最佳编程语言及其应用
    本文介绍了学习恶意软件分析和逆向工程领域时最适合的编程语言,并重点讨论了Python的优点。Python是一种解释型、多用途的语言,具有可读性高、可快速开发、易于学习的特点。作者分享了在本地恶意软件分析中使用Python的经验,包括快速复制恶意软件组件以更好地理解其工作。此外,作者还提到了Python的跨平台优势,使得在不同操作系统上运行代码变得更加方便。 ... [详细]
  • Java在运行已编译完成的类时,是通过java虚拟机来装载和执行的,java虚拟机通过操作系统命令JAVA_HOMEbinjava–option来启 ... [详细]
  • 第四讲ApacheLAMP服务器基本配置Apache的编译安装从Apache的官方网站下载源码包:http:httpd.apache.orgdownload.cgi今 ... [详细]
  • 原文地址http://balau82.wordpress.com/2010/02/28/hello-world-for-bare-metal-arm-using-qemu/最开始时 ... [详细]
  • linux 字符串数组初始化,C++字符数组初始化方法的分析
    发现了一个字符数组初始化的误区,而这个往往能导致比较严重的性能问题,分析介绍如下:往往我们在初始化一个字符数组,大概有如下几 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 本文讨论了在数据库打开和关闭状态下,重新命名或移动数据文件和日志文件的情况。针对性能和维护原因,需要将数据库文件移动到不同的磁盘上或重新分配到新的磁盘上的情况,以及在操作系统级别移动或重命名数据文件但未在数据库层进行重命名导致报错的情况。通过三个方面进行讨论。 ... [详细]
  • ejava,刘聪dejava
    本文目录一览:1、什么是Java?2、java ... [详细]
  • C语言的经典程序有哪些
    本篇内容介绍了“C语言的经典程序有哪些”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何 ... [详细]
  • 开发笔记:Python之路第一篇:初识Python
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了Python之路第一篇:初识Python相关的知识,希望对你有一定的参考价值。Python简介& ... [详细]
  • RingBuffer,或者说CircularBuffer,是一个长度固定的缓冲区,当从一端插入元素超过指定的最大长度时,缓冲区另一端的元素 ... [详细]
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社区 版权所有