首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

gcc:如何在函数输入时保存所有已使用的寄存器

gcc是GNU Compiler Collection的缩写,是一套广泛使用的编程语言编译器。在函数输入时,gcc会根据函数的调用约定来保存和恢复已使用的寄存器。

函数调用约定是一种规范,用于定义函数如何在调用和返回时处理寄存器。常见的函数调用约定有C调用约定和标准调用约定。

在C调用约定中,函数的参数通过栈传递,而返回值通常通过寄存器传递。在函数调用前,gcc会将需要使用的寄存器的值保存到栈上,以便在函数执行过程中可以使用这些寄存器。保存寄存器的操作通常由编译器自动完成,无需手动干预。

对于标准调用约定,函数的参数和返回值都通过栈传递。在函数调用前,gcc会将需要使用的寄存器的值保存到栈上,以便在函数执行过程中可以使用这些寄存器。保存寄存器的操作通常由编译器自动完成,无需手动干预。

总结起来,gcc在函数输入时会根据函数调用约定自动保存所有已使用的寄存器,以确保函数执行过程中可以正确使用这些寄存器。这个过程由编译器自动完成,无需手动干预。

腾讯云相关产品和产品介绍链接地址:

  • 腾讯云函数计算(SCF):https://cloud.tencent.com/product/scf
  • 腾讯云云服务器(CVM):https://cloud.tencent.com/product/cvm
  • 腾讯云容器服务(TKE):https://cloud.tencent.com/product/tke
  • 腾讯云数据库(TencentDB):https://cloud.tencent.com/product/cdb
  • 腾讯云安全加密服务(KMS):https://cloud.tencent.com/product/kms
  • 腾讯云人工智能(AI):https://cloud.tencent.com/product/ai
  • 腾讯云物联网(IoT):https://cloud.tencent.com/product/iotexplorer
  • 腾讯云移动开发(移动推送、移动分析、移动测试等):https://cloud.tencent.com/product/mobile
  • 腾讯云对象存储(COS):https://cloud.tencent.com/product/cos
  • 腾讯云区块链服务(BCS):https://cloud.tencent.com/product/bcs
  • 腾讯云元宇宙服务(Tencent XR):https://cloud.tencent.com/product/xr
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

51单片机系列有哪些类型_51单片机1602液晶显示原理

实物图 原理图 RS:1为数据/0为指令;RW:1为读/0为写;E1为数据有效,下降沿执行指令 示例代码 main.c #include "reg52.h" //此文件中定义了单片机一些特殊功能寄存器...: 延时函数,延时1ms * 入 : c * 出 : 无 * 说 名 : 该函数是在12MHZ晶振下,12分频单片机延时。...; //设置数据指针起点 } #endif lcd.h #ifndef __LCD_H_ #define __LCD_H_ /********************************** 当使用是...4位数据传输时候定义, 使用8位取消这个定义 **********************************/ //#define LCD1602_4PINS /****************...本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。发现本站有涉嫌侵权/违法违规内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

73610

《深入理解计算机系统》阅读笔记--程序机器级表示(上)

三、程序编码 假如我们有一个c程序,有两个文件p1.c 和p2.c 我们通常编译时候是通过如下命令: gcc -0g -o p p1.c p2.c GCC是linux上默认编译器,-0g 告诉编译器使用会生成符合原始...GCC命令调用了一整套程序,将源代码转换为可执行代码: C预处理器扩展源代码,插入所有用#include 命令指定文件,并扩展所有用#define声明制定宏。...有的寄存器用于记录某些重要程序状态,而其他寄存器用来保存临时数据。 条件码寄存器保存着最近执行算术或逻辑指令状态信息。...,不需要访问该程序源代码或汇编代码 反汇编器使用指令命令规则与GCC生成汇编代码使用有些区别,在上面的示例中,它省略了很多指令结尾q,这些后缀是大小指示符,可以省略 四、数据格式 由于是从16位体系结构扩展成...上图中记录是两类数据移动指令,在将较小源值赋值到较大目的时候使用所有这些指令都把数据从源(在寄存器或内存中)复制到目的寄存器

75300
  • X86 寻址方式、AT&T 汇编语言相关知识、AT&T 与 Intel 汇编语言比较、gcc 嵌入式汇编

    ),余数保存在edx 寄存器中。...四、gcc 嵌入式汇编 在Linux 源代码中,有很多C 语言函数中嵌入一段汇编语言程序段,这就是gcc 提供“asm”功能,例如在include/asm-i386/system.h 中定义...数字前加前缀“%“,%1,%2 等表示使用寄存器样板操作数。可以使用操作数总数取决于具体CPU 中通用寄存器数量,Intel 可以有8 个。...由于这些样板操作数前缀使用了“%”,因此,在用到具体寄存器时就在前面加两个“%”,%%cr0。...如果输入部分一个操作数所要求使用寄存器,与前面输出部分某个约束所要求是同一个寄存器,那就把对应操作数编号(“1”,“2”等)放在约束条件中,在后面的例子中,我们会看到这种情况。

    3.1K00

    【嵌入式】基于ARM嵌入式Linux开发总结

    5、寄存器: (1)ARM处理器均为32位寄存器; (2)ARM1176寄存器数量:40个 (3)ARM1176寄存器包括:未分组寄存器、分组寄存器、CPSR、SPSR; (4)未分组寄存器所有模式通用..., SPSR_und,SPSR_svc,SPSR_mon (6)可复用寄存器: ① SP堆栈指针寄存器-R13,用于保存子程序调用或异常处理临时数据; ② LR连接寄存器-R14,用于保存子程序调用或异常处理时...(7)PSR程序状态寄存器: ① 包括CPSR当前程序状态寄存器和SPSR备份程序状态寄存器; ② CPSP用于保存当前模式下处理器模式、状态、中断使能、大小端模式及条件位等信息; ③ SPSR...二、开发工具用法 1、Vi工作模式及其切换-掌握使用Vi完成源代码编辑、保存及退出常见按键操作; 2、GCC:GNU Compiler Collection,GUN编译器套件,特点: ① 支持绝大多数高级语言编译...1)fork()函数说明 fork()函数用于从存在进程中创建一个新进程。新进程称为子进程,而原进程称为父进程。

    18.4K21

    MIPS架构深入理解11-向MIPS移植软件之编程语言

    如果我们直接使用C语言*乘法操作符,生成乘法汇编指令一般只使用两个操作数,而且隐含地将生成double类型结果保存到hi/lo寄存器中。...inline内联函数,这意味着应该使用函数逻辑代码拷贝去替代调用这个函数地方代码(这允许局部寄存器优化)。...%0意思就是指向索引为0变量,也就是p。首先,我们使用=修改符指明这个值是write-only;其次,通过符号r告诉GCC,可以自由选择任何一个通用寄存器保存这个值。...asm()中第3行代码,告诉GCC,操作数%1和%2分别是a和b,并且允许GCC将其保存到任何通用目的寄存器中。 示例函数最后,就是表明,把结果返回给调用者。...2 内存映射I/O寄存器和volatile 因为在MIPS架构中,将所有的I/O寄存器映射到内存上,可以很容易使用C语言编写代码进行访问。所以,不到迫不得,不要使用汇编语言操作这些I/O寄存器

    1.2K30

    深入理解计算机系统(3.7)------过程(函数调用原理)

    4、寄存器使用惯例   程序寄存器组是唯一能够被所有过程共享资源。...为此必须采用一组统一寄存器使用惯例,所有的过程都必须遵守,包括程序库过程。   假如没有这些规矩,比如在调用一个过程时,无论是调用者还是被调用者,都可能更新寄存器值。...②、可以将 y 保存在被调用者保存寄存器中。如果 Q ,或者其它 Q 调用程序想使用这个寄存器,它必须将这个寄存器保存在帧栈中,并在返回前恢复该值。换句话说就是被调用者保存这个值。...我们通过如下指令编译成汇编代码: gcc -O0 -S function.c   为了完整展现那8个步骤,因此给变量c加了register关键字修饰,这将会将c送入寄存器,从而更改被调用者保存寄存器,...6、总结   本章对于函数汇编实现做了详细讲解,主要是栈规则机制,帮我们解决了数据如何在调用者和被调用者之间传递,以及在被调用者当中局部变量内存分配以及释放。

    1.5K50

    不懂底层程序员不是好程序员,解密代码在计算机中运行原理

    计算机基本架构 想要了解程序如何在计算机中运行,以及C/C++编程中设计内存、地址、指针等概念,就必须要先了解计算机基本架构; ?...在C++程序中向函数在实参传递时会将实参存入寄存器,需要反复重复使用变量也最好放到寄存器中。...由于CPU运行速度远高于内存读写速度,因此CPU如果直接从内存中存取数据就需要等待一定时间,但是Cache能保存着CPU刚用过或循环使用一部分数据,这样当下次CPU使用该部分数据时可从Cache中直接调用...5、CPU 从寄存器和内存中取得操作数。这步可能会包含地址计算。 6、使用步骤 3 得到操作数,CPU 执行该指令。...同时更新部分状态标志位,零标志 (Zero)、进位标志 (Carry) 和溢出标志 (Overflow)。 7、输出操作数,若输出也是指令一部分CPU 还需要存储其结果操作数。 ?

    1.4K20

    【编程基础】C函数调用过程

    这几天在看GCC Inline Assembly,在C代码中通过asm或__asm__嵌入一些汇编代码,进行系统调用,使用寄存器以提高性能能,需要对函数调用过程中堆栈帧(Stack Frame)、CPU...寄存器GCC inlie assembly等了如指掌。...(3) 保存调用方函数EBP寄存器,即将调用方函数EBP压入堆栈,并令EBP指向此栈中地址:pushl %ebp; movl %esp, %ebp。由被调函数执行。...(4) 上下文:保存函数调用过程中需要保持不变寄存器函数调用方),ebx,esi,edi等。由被调函数执行。 (5) 临时变量,非静态局部变量。 下面是一个函数堆栈帧结构图: ?...压入函数参数和返回地址过程是由函数调用方在调用函数之前将其压入栈中,每个函数执行后首先要执行就是把函数调用方EBP寄存器压入栈中,之后是在栈上开辟一些空间存放局部变量,最后把要保存寄存器压入栈中

    91650

    Win32 Linux汇编语法区别

    所有的系统调用功能号都可以在文件 /usr/include/bits/syscall.h 中找到,为了便于使用,它们是用 SYS_ 这样宏来定义 SYS_write、SYS_exit...或许你已经发现,在进行系统调用时至多只有 5 个寄存器能够用来保存参数,难道所有系统调用参数个数都不超过 5 吗?...系统调用完成之后,返回值仍将保存寄存器 eax 中。 由于只是需要一块连续内存区域来保存系统调用参数,因此完全可以像普通函数调用一样使用栈(stack)来传递系统调用所需参数。...在GCC内联汇编语句指令部中,加上前缀’%'数字(%0,%1)表示就是需要使用寄存器”样板”操作数。...有时在进行某些操作时,除了要用到进行数据输入和输出寄存器外,还要使用多个寄存器保存中间计算结果,这样就难免会破坏原有寄存器内容。

    2.4K40

    Linux系统调用原理

    system_call 过程获取 eax 寄存器值,然后通过 eax 寄存器值找到要调用 系统调用 入口,并且进行调用。调用完成后,系统调用 会把返回值保存到 eax 寄存器中。...Linux 使用寄存器来传递参数,参数与寄存器关系如下: 第1个参数放置在 ebx 寄存器。 第2个参数放置在 ecx 寄存器。 第3个参数放置在 edx 寄存器。...而 Linux 进入中断处理程序时,会把这些寄存器保存到内核栈中,这样 系统调用 就能通过内核栈来获取到参数。...))) 就是告诉 GCC 所有参数都从栈中读取,而 Linux 进入中断处理上下文时,会把 ebx、ecx、edx、esi、edi、ebp 寄存器保存到内核栈中,那么 系统调用 就可以从内核栈获取到参数值...但由于寄存器只能传递 32 位整型值(x86 CPU),所以参数一般只能传递指针或者整型数值,如果要获取指针对应结构数据,就必须通过从用户空间复制到内核空间, sys_open() 系统调用获取要打开文件路径

    4.2K30

    函数调用约定

    但是这样在使用者来看是不现实,完全顺序执行代码在编程初期就被发现不适合开发。于是人们增加了循环,判断,跳转和函数函数开始作为几乎所有编程语言基础。...但是仍然有不使用函数编程方式,通过大量使用label和jump,不适用函数而在不同过程代码中跳转在高性能编程里也是有市场。因为这样省去了函数调用开销(入栈出栈,保存上下文等)。...函数典型特点是传递参数,返回结果。几乎所有的编程语言都需要设计如何传递参数,如何返回函数执行结果。...函数调用约定主要解决这几个问题: l 参数以什么顺序入栈或者以什么顺序进入寄存器完成传递 l 调用其它函数时候要保存函数寄存器现场,谁来保存保存哪些寄存器 l 函数退出时候要恢复调用者寄存器现场...从右向左入栈,调用者不保存寄存器,但是清理 调用方 Os/2 Thiscall(gcc) 与cdel一样,区别是this指针作为最后一个参数入栈 调用方 Thiscall(win

    2.3K20

    __asm__ volatile 之 C语言嵌入式汇编

    备注:在原文基础上,增加了标题,方便大家阅读。 AT&T ASM Syntax(内嵌汇编) 1、寄存器使用:引用寄存器要在寄存器号前加百分号%,“movl %eax, %ebx”。...所以那条if语句判断条件(*__p) == 9999肯定是为true,所以GCC就不再生成相关代码,而是直接根据为true条件生成return 5汇编代码(GCC使用eax作为保存返回值寄存器...反过来,你也可以为Output指定可选约束,比如"r","g"等,让GCC为其选择到底使用哪个寄存器,还是使用内存方式,GCC在选择时候,会首先排除掉已经被Input操作表达式使用所有寄存器,然后在剩下寄存器中选择...如果你在一个内联汇编语句Clobber/Modify域向GCC声明某个寄存器内容发生了改变,GCC在编译时,如果发现这个被声明寄存器内容在此内联汇编语句之后还要继续使用,那么GCC会首先将此寄存器内容保存起来...Linux 2.4所有i386平台相关内联汇编代码中都没有使用这一点,但S390平台相关代码中有用到,但由于我对S390汇编没有任何概念,所以,也不知道这么做意义何在

    12.4K45

    逆向工程——栈

    用途 保存函数结束时返回地址 x86 当程序使用call指令调用其他函数时,call指令结束后返回地址将被保存到栈里,在call所调用函数结束之后,程序将执行无条件跳转指令,跳转到这个返回地址...ARM ARM程序也使用保存返回地址,只是略有不同。之前课程中我们看到“hello world”程序返回地址保存在LR寄存器里。...但是如果程序还会继续调用其它函数,就需要在调用函数之前保存LR寄存器里面的值。通常函数会在启动过程中(序言处)保存LR寄存器值。...叶函数特点是:它不必保存LR寄存器值。如果叶函数代码短到用不到几个寄存器,那么它也可能根本不会使用数据栈。所以调用叶函数时候确实可能不会涉及栈操作。...,并非常规函数缘故,这个程序并没有使用栈,而是使用EAX寄存器来传递alloca()函数唯一参数。

    88231

    Linux进程上下文切换过程context_switch详解--Linux进程管理与调度(二十一)

    使用地址空间 由于不同架构下地址映射机制有所区别, 而寄存器等信息弊病也是依赖于架构, 因此switch_mm和switch_to两个函数均是体系结构相关 3.1 context_switch...而因为每个进程首先都是从核心态开始执行(在调度期间控制权传递给新进程), 在返回用户空间时, 会使用内核栈上保存值自动恢复寄存器数据...., 而switch_to之后代码只有在当前进程下一次被选择运行时才会执行 执行环境切换是在switch_to()中完成, switch_to完成最终进程切换,它保存原进程所有寄存器信息,恢复新进程所有寄存器信息...关键点:内核寄存器[eflags、ebp保存到内核栈;内核栈esp地址、ip地址保存到thread_info中,task_struct在生命期中始终是全局,所以肯定能根据该结构恢复出其所有执行场景来]...* memory强制gcc编译器假设RAM所有内存单元均被汇编指令修改,这样cpu中registers和cache中缓存内存单元中数据将作废。cpu将不得不在需要时候重新读取内存中数据。

    4.4K31

    GNU C 内联汇编介绍

    最近由于某种需求,看到了相关 C 语言代码。也就自然去简单学习了一下如何在 C 代码中内嵌汇编指令。...2、\n 用于指令换行,\t使 GCC 编译时候产生汇编指令格式保持规范。 GCC 默认使用 AT&T 格式汇编语法 它与 intel 汇编语法之间稍有不同。...---- 破坏寄存器列表 1、这一行告诉 GCC 在内联汇编代码中,哪些寄存器可能会被使用到(显式/隐式)。那么 GCC 就会在进入内联汇编之前将这些寄存器保存起来,最后再恢复。...避免影响到其他代码。 早期 GCC 要求把输入、输出用到寄存器写到破坏列表里面。但是现在编译器能够自动保存、恢复在输出、输入列表里面用到寄存器。...---- GCC 一些新特性 1、新 GCC 允许我们为随机分配寄存器命名,这样极大方便我们编写内联汇编代码。

    2K10

    程序编译、链接、装载与运行

    参数则会对所有包含指令段进行反汇编,因此使用如下命令就可以获取代码段详细信息objdump -s -d hello.o .data 段保存初始化全局变量和局部静态变量 .bass 段保存未初始化全局变量和局部静态变量注...每一个栈帧保存了一个函数的如下信息 函数参数和返回地址 临时变量,包括非静态局部变量和编译生成其它临时变量 保存上下文 一个函数被调用时将会有如下操作 把所有的参数压入栈中,有些参数也可以不压栈而通过寄存器进行传递...用户程序调用系统调用过程如下: 用户程序先根据调用惯例注7把中断处理函数所需要参数保存在指定寄存器中,例如 eax 寄存器就应该保存系统调用编号,eax = 1 对应系统调用 exit,eax...中断处理函数寄存器 eax 中获取到系统调用编号,根据系统调用编号找到指定系统调用函数 系统调用函数从约定好寄存器中获取所需参数,系统调用函数根据参数开始执行 系统调用执行完毕后,将系统调用结果存放在用户程序有权访问区域...为了保存程序在运行时产生全局变量 数据段:只能保存在编译时产生变量 栈:只能在当前方法内部保存变量 系统调用调用惯例和函数调用有些类似,但是系统调用使用寄存器而不是栈作为参数传递载体 因为系统调用本质上也是函数

    1.3K10

    GCC -O0 -O1 -O2 -O3 四级优化选项

    l -fcprop-registers:因为在函数中把寄存器分配给变量, 所以编译器执行第二次检查以便减少调度依赖性(两个段要求使用相同寄存器)并且删除不必要寄存器复制操作。...-O2(氧气优化) 是比 O1 更高级选项,进行更多优化。Gcc 将执行几乎所有的不包含时间和空间折中优化。...(如果调用多个函数, 这样能够节省时间, 因为只进行一次寄存器保存和恢复操作, 而不是在每个函数调用中都进行。)...这种优化实施依赖特定存在信息:.text.hot 用于告知访问频率较高函数,.text.unlikely 用于告知基本不被执行函数。...虽然这样对于减少代码长度不利, 但是通过最充分利用指令缓存代码, 而不是在每次函数调用时进行分支操作, 可以提高性能。 l -fweb:构建用于保存变量寄存器网络。

    4K30

    Linux内核同步机制之(一):原子操作

    我们c代码是gcc来处理,当遇到嵌入汇编代码时候,gcc会将这些嵌入式汇编文本送给gas进行后续处理。这样,gcc需要了解嵌入汇编代码对寄存器修改情况,否则有可能会造成大麻烦。...例如:gcc对c代码进行处理,将某些变量值保存寄存器中,如果嵌入汇编修改了该寄存器值,又没有通知gcc的话,那么,gcc会以为寄存器中仍然保存了之前变量值,因此不会重新加载该变量到寄存器,而是直接使用这个被嵌入式汇编修改寄存器...还好,在output operand list 和 input operand list中涉及寄存器都不需要体现在clobber list中(gcc分配了这些寄存器,当然知道嵌入汇编代码会修改其内容)...其中%3就是input operand list中"r" (&v->counter),r是限制符(constraint),用来告诉编译器gcc,你看着办吧,你帮我选择一个通用寄存器保存该操作数吧。...编译器在处理嵌入式汇编时候,倾向使用尽可能少寄存器,如果output operand没有&修饰的话,汇编指令中input和output操作数会使用同样一个寄存器

    2K20

    深入理解计算机系统(第三版) CSAPP 杂谈,第3章:程序机器级表示

    大部分指令都会有这4种变种,但pushq,popq,leaq等指令没有 movz,movs是0扩展和符号扩展指令,将较小数从寄存器或内存转移到寄存器中。...也可以利用寄存器jmp *%rax表示跳转到%rax地址,jmp *(%rax)表示跳转到%rax值对应内存值内存地址去。...和SET一样,也有je,js,jle等指令 GCC当switch情况较多,且跨度较小时候,会使用地址跳转表来翻译switch 当x86-64过程需要存储空间超出寄存器能够存放大小时,...就回在栈上分配空间,这个部分称为过程栈帧 call指令用于函数调用,此时将会把将紧跟着当前地址后面的那条指令地址压入栈,并吧要跳转函数地址设置到PC。...局部数据存到需要内存中几种情况: 寄存器不够用 对局部变量使用了地址运算符& 某些局部变量是数组或结构体(如果优化了则不一定) 数据对齐可提高软件性能,减少读次数和额外处理。

    1.1K10
    领券