x86-64 System V ABI保证在调用之前进行16字节的堆栈对齐,因此,允许libc系统将其用于16字节的对齐加载/存储.如果您破坏了ABI,那么当事情崩溃时,这就是您的问题.

在进入某个函数时,在调用推送了一个返回地址之后,RSP -8会对齐16个字节,再按一次将使您可以调用另一个函数.

当然,通过使用奇数次压入或使用sub rsp,16 * n 8来保留堆栈空间,GCC当然通常没有问题.只要您仅读取变量而不分配变量,就可以将带有asm(“ rsp”)的register-asm局部变量与asm(“ rsp”)配合使用.

您说您正在使用GCC7.3. I put your code on the Godbolt compiler explorer并使用-O3,-O2,-O1和-O0进行编译.它在所有优化级别上都遵循ABI,使之成为以sub rsp,8开头的主函数,并且直到函数结束时才修改函数内部的RSP(调用除外).

我检查过的clang和gcc的所有其他版本和优化级别也是如此.

这是gcc7.3 -O3的代码源:请注意,除了在函数体内读取RSP以外,它对RSP均无任何作用,因此,如果使用有效的RSP(16字节对齐-8)调用main,则main的所有功能还将使用16字节对齐的RSP进行调用. (并且它永远不会发现sp& 8为真,因此它永远不会首先调用system.)

# gcc7.3 -O3

main:

sub rsp, 8

xor eax, eax

mov edi, OFFSET FLAT:.LC0

mov rsi, rsp # read RSP.

call printf

test spl, 8 # low 8 bits of RSP

je .L2

mov edi, OFFSET FLAT:.LC1

call puts

mov edi, OFFSET FLAT:.LC2

call system

.L2:

xor eax, eax

add rsp, 8

ret

如果您以某种非标准方式呼叫main,则违反了ABI.而且您不在问题中解释它,所以这不是MCVE.

正如我在Does the C++ standard allow for an uninitialized bool to crash a program?中所述,允许编译器发出利用目标平台ABI所做的任何保证的代码.这包括使用movaps进行16字节的加载/存储,以利用传入的对齐保证来在堆栈上复制内容.

gcc不能像clang那样完全优化if(),这是错过的优化.

但是clang确实将其视为未初始化的变量.我认为,它没有在asm语句中使用它,因此本地寄存器asm(“ rsp”)对clang无效. Clang在第一个printf调用之前不修改RSI,所以clang的main实际上打印argv,根本不读取RSP.

允许Clang执行此操作:register-asm本地vars唯一受支持的用法是使“ r”(var)Extended-asm约束选择所需的寄存器. (https://gcc.gnu.org/onlinedocs/gcc/Local-Register-Variables.html).

该手册并不意味着仅仅在其他时间使用这样的变量可能会有问题,因此我认为,根据书面规则,该代码通常应该是安全的,并且可以在实践中使用.

手册确实说过使用调用优先寄存器(如x86上的“ rcx”)会导致变量被函数调用所破坏,所以也许使用rsp的变量会受到编译器生成的push / pop的影响吗?

这是一个有趣的测试用例:在Godbolt链接上查看.

// gcc won't compile this: "error: unable to find a register to spill"

// clang simply copies the value back out of RDX before idiv

int sink;

int divide(int a, int b) {

register long long int dx asm ("rdx") = b;

asm("" : "+r"(dx)); // actually make the compiler put the value in RDX

sink = a/b; // IDIV uses EDX as an input

return dx;

}

没有asm(“”:“ r”(dx));, gcc会很好地进行编译,根本不会将b放入RDX中.

linux修改栈指针x86,x86-堆栈指针未填充16时libc的system()导致分段...相关推荐

  1. linux修改栈指针x86,为什么x86-64 Linux系统调用会修改RCX,这个值意味着什么?

    我正在尝试使用sys_brk syscall在linux中分配一些内存.这是我尝试过的: BYTES_TO_ALLOCATE equ 0x08 section .text global _start ...

  2. linux server 5.5下载地址,《红帽Linux 5.5 for x86 服务器版》(RedHat Enterprise Linux Server 5.5 for x86)...

    红帽Linux 5.5 for x86 服务器版已经有下载了. RHEL5的版本主要分为Sever和Desktop两个版本. 具体来说,Server版本分为: Red Hat Enterprise L ...

  3. Linux系统调用表:x86和x86_64

    <Linux系统调用表> <linux系统调用表(system call table)> <线上环境 Linux 系统调用追踪> <Linux系统调用权威指南 ...

  4. Linux SPI 子系统(x86平台)

    Linux SPI 子系统(x86平台) 文章目录 Linux SPI 子系统(x86平台) 前言 总述 SPI 硬件系统与软件抽象之间的关系 SPI 驱动的 Probe 和 Match 过程 SPI ...

  5. C语言及ARM中堆栈指针SP设置的理解与总结

    1什么是栈 百度这么说:栈是一种特殊的线性表,是一种只允许在表的一端进行插入或删除操作的线性表.表中允许进行插入.删除操作的一端称为栈顶.表的另一端称为栈底.栈顶的当前位置是动态的,对栈顶当前位置的标 ...

  6. 51单片机中断的调用寄存器组(PSW)的作用,以及汇编堆栈的作用,堆栈指针的SP的使用方法,RAM的运行和ROM在单片机具体运行和C语言的优势和中断,定时器基础知识(上)

    一,堆栈在汇编的作用,以及PUSH ACC 和 PUSH PSW 通过最简单的8051单片机RAM的分配可知,单片机从烧程序到达到一定的工作过程.首先明白为什么要引如"烧"写的过程 ...

  7. 在gem5的full system下运行 x86编译的测试程序 running gem5 on ubuntu in full system mode in x86...

    背景 上篇博客写了如何在gem5的full system模式运行alpha的指令编译的程序,这篇博客讲述如何在gem5的full system模式运行x86指令集编译的程序,这两种方式非常类似. 首先 ...

  8. linux 杀掉php,Linux_在Linux系统中使用xkill命令杀掉未响应的进程,我们如何在Linux中杀掉一个资 - phpStudy...

    在Linux系统中使用xkill命令杀掉未响应的进程 我们如何在Linux中杀掉一个资源/进程?很明显我们会找出资源的pid然后用kill命令. 说的更明白一点,我们可以找到某个资源(比如termin ...

  9. Linux修改资源限制详解

    Linux修改资源限制详解 ulimit -a 临时设置,和永久设置 1.core file size 2.data seg size 3.scheduling priority 4.file siz ...

最新文章

  1. mkdir()提示No such file or directory错误的解决方法
  2. 记录一次阿里云服务器升级报错
  3. RecyclerView添加header与footer
  4. 移动搜索引擎-网页信息预处理
  5. HTTP Session、Cookie机制详解
  6. 爬虫1_python2
  7. linux dialog 源码,Linux dialog详解(图形化shell)
  8. python spider怎么用_python爬虫入门(七)Scrapy框架之Spider类
  9. php正则表达式匹配逗号,数字和逗号PHP正则表达式只
  10. 台达编码器型号含义_光电编码器型号含义_光电编码器应用实例
  11. 数论二(hdoj 卡特兰数)
  12. 基于FVC_MSAVI_EVI的荒漠化等级分类方法
  13. 统一项目管理平台(UMPlatForm.NET) - 5.1 数据字典管理模块
  14. atitit.科技公司的超级武器--超级框架,到底要不要自己的框架??
  15. 如何通过iTunes安装ipa测试包
  16. 红帽子linux命令界面,红帽子_Linux_命令全解
  17. Windows电脑如何查看内存条配置
  18. How to Reassign Workflow Task in Sharepoint 2007
  19. 坚持自主可控,长安链ChainMaker全面拥抱国密的技术实践
  20. 做中国的Salesforce,神州云动凭的是什么?

热门文章

  1. Oracle 练习题 20131021 for 循环练习
  2. VB.NET判断一个路径的文件是否存在
  3. 华为交换机S3700-TELNET远程管理交换机配置
  4. 简易数字时钟软件详细制作过程
  5. 对一道基础string题及其变式题的思考与解析
  6. vite + vue2 + eslint 项目配置
  7. python都有哪些包装_Python基础:21包装
  8. rc时间常数公式_你知道RC电路和RL电路中时间常数的来源以及和时间的关系吗?...
  9. 建筑与计算机技术,建筑设计中常用的计算机技术与注意点
  10. java借口案例实现_java实现接口的典型案例