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

如何告诉编译器不要在_Noreturn函数的内联asm之后生成"retq“?

在C语言中,_Noreturn函数用于指示该函数不会返回到调用点。在一些特殊情况下,我们可能希望告诉编译器不要在_Noreturn函数的内联汇编代码之后生成"retq"指令,以避免生成无用的代码。

要告诉编译器不要在_Noreturn函数的内联汇编之后生成"retq"指令,可以使用GCC的扩展语法来实现。具体的做法是在内联汇编代码块的最后插入一个特殊的标记"__builtin_unreachable()",这个标记告诉编译器在此处不会执行到,因此不需要生成"retq"指令。

下面是一个示例代码:

代码语言:txt
复制
#include <stdio.h>

_Noreturn void foo() {
    asm volatile (
        "mov $1, %%rax\n\t"
        "int $0x80"
        ::: "rax"
    );
    __builtin_unreachable();
}

int main() {
    foo();
    printf("This line will never be reached.\n");
    return 0;
}

在上面的代码中,函数foo()被声明为_Noreturn函数,表示该函数不会返回。在函数内部的内联汇编代码块中,我们使用了一个简单的汇编指令来退出程序。在汇编代码之后,我们插入了"__builtin_unreachable()"标记,告诉编译器在此处不会执行到。

通过使用这种方式,我们可以告诉编译器不要在_Noreturn函数的内联汇编之后生成"retq"指令,从而避免生成无用的代码。

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

  • 腾讯云官网:https://cloud.tencent.com/
  • 云服务器(CVM):https://cloud.tencent.com/product/cvm
  • 云原生应用引擎(TKE):https://cloud.tencent.com/product/tke
  • 云数据库 MySQL 版(CMYSQL):https://cloud.tencent.com/product/cmysql
  • 云存储(COS):https://cloud.tencent.com/product/cos
  • 腾讯云区块链服务(TBaaS):https://cloud.tencent.com/product/tbaas
  • 腾讯云物联网平台(TIoT):https://cloud.tencent.com/product/tiot
  • 腾讯云移动开发平台(MPS):https://cloud.tencent.com/product/mps
页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

__attribute__机制介绍

format语法格式为: format ( archetype,  string-index,  first-to-check ) format属性告诉编译器,按照printf,scanf,strftime...注意,默认情况下,编译器是能识别类似printf“标准”库函数。 3. noreturn 该属性通知编译器函数从不返回值。...恰好在函数入口之后并恰好在函数出口之前,将使用当前函数地址和调用地址来调用下面的profiling函数。...如果函数包含内联,而所有使用到该函数程序都要把该内联展开,这会额外地增加代码长度。如果要在C 代码中使用extern inline声明,必须提供这种函数可寻址形式。...例如: struct S { short f[3]; } __attribute__ ( (aligned) ); 上面,aligned后面紧跟一个指定数字值,编译器将依据你目标机器情况使用最大最有益对齐方式

2.9K11

内联汇编很可怕吗?看完这篇文章,终结它!

这篇文章,我们就来详细聊一聊在 C 语言中,如何通过 asm 关键字来嵌入汇编语言代码,文中 8 个示例代码从简单到复杂,逐步深入地介绍内联汇编关键语法规则。...; 关键字 asm 可以使用 asm 来替换; volatile 是可选编译器有可能对汇编代码进行优化,使用 volatile 关键字之后告诉编译器不要优化手写内联汇编代码。...C 代码中; 输入操作数列表:C 代码如何把数据传递给内联汇编代码; 改动寄存器:告诉编译器,在内联汇编代码中,我们使用了哪些寄存器; “改动寄存器”可以省略,此时最后一个冒号可以不要,但是前面的冒号必须保留...) (1)约束 就是通过不同字符,来告诉编译器使用哪些寄存器,或者内存地址。...; &:在内联函数完成之前,可以删除或者重新使用被修饰操作数; 语言描述比较抽象,直接看例子!

2K20

c语言内嵌汇编代码之Clobbers用途到底是什么

在阅读本文之前,请先阅读gcc相关文档,确保对如何在c中使用汇编语言有个基本认识。...它目的是为了告知编译器,Clobbers 列表中寄存器会被该asm语句中汇编代码隐性修改。 3....通俗来讲,Clobbers 用途就是为了告诉编译器,我这里指定这些寄存器在该asm语句汇编代码中用了,你在编译这条asm语句时,如果需要用到寄存器,别用我这里指定这些,否则就都乱了。 5....在执行完这条asm语句之后,这些寄存器值会再被重新load回来,然后再执行这条asm语句后面的逻辑。这样就保证了所有操作用到数据都是最新,是正确。...这是因为,gcc在编译时,根本就不会分析asm汇编代码,所以它也就不知道我们已经使用了eax寄存器,所以才导致最终冲突。 那我们怎样才能告诉gcc,我们已经用了eax寄存器,让它别再用了呢?

2.8K30

c语言内嵌汇编代码之constraint modifier中 = 和 + 区别

在阅读本文之前,请先阅读gcc相关文档,确保对如何在c中使用汇编语言有个基本认识。.... = 表示可写,是告诉编译器在执行这条asm语句时,该 output operand 原来值不会被用到,所以它占用寄存器或内存在写操作发生之前可以被随便使用。.... + 表示可写,是告诉编译器在执行这条asm语句时,该 output operand 原来值会被用到,所以它占用寄存器或内存不能被随便使用,否则可能会导致在该 output operand 被使用时...6. + 是在 = 基础上,对编译器更严格限制。...而在inc2方法中,我们指定 constraint modifier 是 +,表示a原来值在汇编代码中会被用到,所以编译器就不会改变a对应寄存器值,所以最终结果是正确

88220

c语言内嵌汇编代码之InputOperands使用时注意事项

在阅读本文之前,请先阅读gcc相关文档,确保对如何在c中使用汇编语言有个基本认识。...编译器认为asm语句中 input operands 只是用来读数据,不会被修改,所以当该asm语句执行完毕之后,后面的代码如果还有地方使用 input operands,则不管在asm语句汇编代码中有没有修改过...如果想要告知编译器 input operands 在asm语句汇编代码中有被修改过,只能通过将 input operands 绑定到 output operands 形式。.../a.out inc1: 1 inc2: 2 由上可以看到,inc1结果是1,这是因为编译器认为src只是asm语句输入,所以它不会被修改,所以在return时候直接返回了原值。...通过上面的例子我们可以看到,编译器认为asm语句输入参数是只读,所以我们在asm语句汇编代码里也不要去修改输入参数值,如果非要修改,一定要通过某种方式告知编译器,防止最终逻辑错误。

68320

熟悉又陌生arm 编译器详解(armccarmclang)

编译器只执行可以描述为调试信息优化。删除未使用内联函数和未使用静态函数。关掉严重降低调试视图优化。如果与 –debug 一起使用,此选项会给出总体上令人满意调试视图且具有良好代码密度。...这可能导致变量在特定点报告值与期望匹配。 编译器自动内联函数 -O3最大优化。启用调试后,此选项通常会提供较差调试视图。ARM 建议在较低优化级别进行调试。...12345 –use_frame_pointer这个设置栈顶指针,每次进入函数后,会首先将栈顶压入栈,之后再做其他寄存器压栈,这样好处是backtrace调用关系很容易找出来。...asm语句可以在任何需要C++语句地方使用 内联程序集代码中寄存器名被视为C或C++变量。它们不一定与同名物理寄存器有关。...如果寄存器未声明为C或C++变量,编译器生成警告 不得在内联程序集代码中保存和还原寄存器,编译器会执行此操作。此外,内联汇编程序不提供对物理寄存器直接访问。

1.9K40

谈谈C++新标准带来属性(Attribute)

1 [[noreturn]] 从字面意义上来看,noreturn是非常容易理解,这个属性含义就是标明某个函数一定不会返回。 请看下面的例子程序: // 正确,函数将永远不会返回。...func2(false); } 这个属性最容易被误解地方是返回值为void函数代表着不会返回,它只是没有返回值而已。...另外,[[noreturn]]只要函数最终没有返回都是可以,比如用exit()调用直接将程序干掉程序也是可以被编译器接受行为(只是暂时没想到为啥要这么干)。...这个属性含义是明确告诉编译器,用此属性修饰函数,其返回值(必须是按值返回)不应该被丢弃,如果在实际调用中舍弃了返回变量,则编译器会发出警示信息。...当然,这并不代表我鼓励你使用它们,明确编译器知道你意图总归是一件好事情。

61520

【CSAPP】AttackLab

发生溢出原因为输入字符串中包括了写返回地址字符串,所以大于40个字节; 溢出条件 为只输入40个字节字符串,写返回地址 但是经检验:当只输入40个字节,写返回地址时:原本应该Type String...getbuf汇编代码: ​​​ 起始地址为4017a8,所以需要在4017a8处设置断点(即还没运行4017a8),查看栈顶指针寄存器%rsp值。...gadget可以使用与编译器生成汇编语言语句相对应代码,尤其是函数末尾代码。在实践中,可能有一些这种形式有用gadget,但不足以实现许多重要操作。...例如,rtarget一个版本包含为以下C函数生成代码: ​​ ​ 这个功能对攻击系统有用可能性似乎很小。...在反汇编文件rtarget.asm中查看farm部分汇编代码: ​​​ 通过搜索48 89 (mov指令),还有对于popq对应机器码,其中 0xc3 = retq ,0x90 = nop, 找到了两个对这个实验有用指令且有效指令

22610

GNU C 内联汇编介绍

也就自然去简单学习了一下如何在 C 代码中内嵌汇编指令。...---- asm/__asm__ 关键字 1、总的来说在 C 代码中我们通过 asm/__asm__ 关键字来告诉编译器将指定内容当汇编指令处理。...这里讲一下 "=r" 用法,像 a, b 这些代码都是指定使用寄存器。但是 r 是让编译器随机给一个,那么我怎么知道是那个呢? 不用担心,编译器为使用随机寄存器遍了一个号。...---- 破坏寄存器列表 1、这一行告诉 GCC 在内联汇编代码中,哪些寄存器可能会被使用到(显式/隐式)。那么 GCC 就会在进入内联汇编之前将这些寄存器保存起来,最后再恢复。..."=r" , "r" 前面加上 [name] 之后,便可以在汇编指令里面直接通过 %[name] 方式使用相应分配寄存器了。

1.9K10

__asm__ volatile 之 C语言嵌入式汇编

在这条内联汇编之前,内存指针__p所指向内存被赋值为9999,随即在内联汇编之后,一条if语句判断__p 所指向内存与9999是否相等。很明显,它们是相等。...那么GCC判断原则是什么?我不知道(如果有哪位朋友清楚的话,请告诉我)。...为了保险起见,如果你不想让GCC优化影响你内联汇编代码,你最好在前面都加上__volatile__,而不要依赖于编译器原则,因为即使你非常了解当前编译器优化原则,你也无法保证这种原则将来不会发生变化...,然后在此内联汇编语句相关生成代码之后,再将其内容恢复。...如果一个内联汇编语句Clobber/Modify域存在"memory",那么GCC会保证在此内联汇编之前,如果某个内存内容被装入了寄存器,那么在这个内联汇编之后,如果需要使用这个内存处内容,就会直接到这个内存处重新读取

12.2K45

【CSAPP】探秘AttackLab奥秘:level 4解密与实战

5.hex2raw 生成字节序列实用程序。参见实验讲义中文档。...-d ctarget > ctarget.asm objdump -d rtarget > rtarget.asm 对ctarget以及rtarget进行反汇编,得到ctarget.asm和...gadget可以使用与编译器生成汇编语言语句相对应代码,尤其是函数末尾代码。在实践中,可能有一些这种形式有用gadget,但不足以实现许多重要操作。...例如,rtarget一个版本包含为以下C函数生成代码: ​​ ​ 这个功能对攻击系统有用可能性似乎很小。...在反汇编文件rtarget.asm中查看farm部分汇编代码: ​​​ 通过搜索48 89 (mov指令),还有对于popq对应机器码,其中 0xc3 = retq ,0x90 = nop, 找到了两个对这个实验有用指令且有效指令

12110

c语言内嵌汇编代码之volatile究竟何时用

在阅读本文之前,请先阅读gcc相关文档,确保对如何在c中使用汇编语言有个基本认识。...4. gcc如果认为一个c函数多条相同asm语句 output operands 结果相同,则可能会只保留其中一条asm语句,在该c函数使用到这条 asm语句 output operands 地方...,统一用相同结果(比如,如果asm语句在循环中,则会提到循环外,如果asm语句在一个c函数中被顺序执行,则只保留第一条asm语句,删除后面的asm语句)。...下面看下把assert方法去掉之后do_check汇编代码: $ gcc -O3 -D NDEBUG main.c && objdump --disassemble=do_check a.out 0000000000001130...通过上面的例子,我们就可以看到 volatile 是如何防止 gcc 优化代码,但是在上面的例子中,该优化是一个正确优化,所以不应该加 volatile。

1.2K10

Rust 安全参考 | Rust 编译到 WebAssembly 可能出现侧信道攻击

像上面这样精心编写恒定时间实现仍然可以由编译器优化为分支指令,这会泄漏choice! 如何阻止编译器优化破坏代码恒定时间呢?有几种方案: 使用 -C opt-level=0 关闭所有优化。...来告诉编译器 &input 内存是易失编译器不应该对它做任何假设 // 起到了一个优化屏障作用 unsafe { core::ptr::read_volatile(&input...出发点在于,我们是否可以影响编译器优化conditional_select函数,而不是全局禁止优化?Cargo 和 rustc 接受全局禁用优化参数,但在整个系统上这样做通常是不可能。...代码生成默认为“快速”指令选择器。该属性不能与 alwaysinline 属性一起使用;此属性也与 minsize 属性和 optsize 属性兼容。...此属性还需要在函数上指定 noinline 属性,因此该函数永远不会内联到任何调用者中。只有具有 alwaysinline 属性函数才是内联到该函数主体有效候选者。

77740

【连载】两百行Rust代码解析绿色线程原理(二)一个能跑通例子

C 具有稳定 ABI,这一属性正是在告诉编译器使用兼容 C-ABI 内存布局。当然,我们结构现在只有一个字段,但我们稍后会添加更多字段。 fn hello() -> !...实际上我们已经劫持了我们 CPU 并使其返回到我们栈。: 内联 ASM 与普通 ASM 略有不同。我们在汇编模板后传递了四个附加参数。..."r" 仅表示将其放入编译器选择通用寄存器中。内联汇编中约束本身是一个很大课题,幸运是我们需求很简单。...: 下一个选项是 clobber 列表,您可以在其中指定编译器不应触及寄存器,并让它知道我们要在汇编代码中管理这些寄存器。...如果我们弹出栈任何值,我们需要在这里指定哪些寄存器并让编译器知道,因此它知道它不能自由地使用这些寄存器。我们不需要它,因为我们返回了一个全新栈。

79220

32位汇编第七讲,混合编程,内联汇编

所以这几个步骤就不写了,生成lib给汇编程序使用,至于手工编译汇编程序,连接汇编程序其实建议去用了,随着编译器提升,以后加选项越来越多 手工生成lib Lib MyAdd.obj   (MyAdd.obj...编译连接之后则会生成DLL,和保存DLL信息lib ? 那么我们工程可以使用了 静态使用 ? 结果 ?...是一样 2.内联汇编调用函数 一丶普通调用无参数调用 上面我们知道怎么写内联汇编了,那么下边我们则可以把这个内联汇编定位为函数 写个ADD函数把 首先我们工程封装成一个函数 ?...显然是不可以,而如果在_asm中 写ret,那么这个函数不知道你返回了所以先定义为void,我们一会解决返回值问题 调用: ?...2.解决普通调用有返回值问题 上面我们如果调用,那么就要自己内联,自己调用,但是很不方便,所以我们加个返回值 直接调用也可以,编译器智慧给警告,因为编译器支持这个语法 调用 ?

1.6K100

在gcc中使用intel风格内联汇编

很简单,内联汇编使用asm(“.intel_syntax noprefix/n”)声明一下,以后内联汇编就可以用intel风格了,构建可执行文件时给gcc加上-masm=intel参数。...因为全局变量变量名会保存在符号表中,所以如果要在内联汇编中使用变量名,也只能使用全局变量变量名。...只为在内联汇编中用名称来访问变量而把一个局部变量变成全局是不合理,所以我们这里也用ebp+offset方式来访问局部变量。...要这么做,就得了解gcc编译时是如何函数分配栈,以及调用函数时寄存器约定是怎样。...,和cl编译器不同是在push ebp前面多出来了几行,有个esp &= -16操作,-16=0xfffffff0,这个作用可能是为了对齐,esp应该是保持16字节对齐

2.8K20
领券