linux修改栈指针x86,x86-堆栈指针未填充16时libc的system()导致分段...
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()导致分段...相关推荐
- linux修改栈指针x86,为什么x86-64 Linux系统调用会修改RCX,这个值意味着什么?
我正在尝试使用sys_brk syscall在linux中分配一些内存.这是我尝试过的: BYTES_TO_ALLOCATE equ 0x08 section .text global _start ...
- 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 ...
- Linux系统调用表:x86和x86_64
<Linux系统调用表> <linux系统调用表(system call table)> <线上环境 Linux 系统调用追踪> <Linux系统调用权威指南 ...
- Linux SPI 子系统(x86平台)
Linux SPI 子系统(x86平台) 文章目录 Linux SPI 子系统(x86平台) 前言 总述 SPI 硬件系统与软件抽象之间的关系 SPI 驱动的 Probe 和 Match 过程 SPI ...
- C语言及ARM中堆栈指针SP设置的理解与总结
1什么是栈 百度这么说:栈是一种特殊的线性表,是一种只允许在表的一端进行插入或删除操作的线性表.表中允许进行插入.删除操作的一端称为栈顶.表的另一端称为栈底.栈顶的当前位置是动态的,对栈顶当前位置的标 ...
- 51单片机中断的调用寄存器组(PSW)的作用,以及汇编堆栈的作用,堆栈指针的SP的使用方法,RAM的运行和ROM在单片机具体运行和C语言的优势和中断,定时器基础知识(上)
一,堆栈在汇编的作用,以及PUSH ACC 和 PUSH PSW 通过最简单的8051单片机RAM的分配可知,单片机从烧程序到达到一定的工作过程.首先明白为什么要引如"烧"写的过程 ...
- 在gem5的full system下运行 x86编译的测试程序 running gem5 on ubuntu in full system mode in x86...
背景 上篇博客写了如何在gem5的full system模式运行alpha的指令编译的程序,这篇博客讲述如何在gem5的full system模式运行x86指令集编译的程序,这两种方式非常类似. 首先 ...
- linux 杀掉php,Linux_在Linux系统中使用xkill命令杀掉未响应的进程,我们如何在Linux中杀掉一个资 - phpStudy...
在Linux系统中使用xkill命令杀掉未响应的进程 我们如何在Linux中杀掉一个资源/进程?很明显我们会找出资源的pid然后用kill命令. 说的更明白一点,我们可以找到某个资源(比如termin ...
- Linux修改资源限制详解
Linux修改资源限制详解 ulimit -a 临时设置,和永久设置 1.core file size 2.data seg size 3.scheduling priority 4.file siz ...
最新文章
- mkdir()提示No such file or directory错误的解决方法
- 记录一次阿里云服务器升级报错
- RecyclerView添加header与footer
- 移动搜索引擎-网页信息预处理
- HTTP Session、Cookie机制详解
- 爬虫1_python2
- linux dialog 源码,Linux dialog详解(图形化shell)
- python spider怎么用_python爬虫入门(七)Scrapy框架之Spider类
- php正则表达式匹配逗号,数字和逗号PHP正则表达式只
- 台达编码器型号含义_光电编码器型号含义_光电编码器应用实例
- 数论二(hdoj 卡特兰数)
- 基于FVC_MSAVI_EVI的荒漠化等级分类方法
- 统一项目管理平台(UMPlatForm.NET) - 5.1 数据字典管理模块
- atitit.科技公司的超级武器--超级框架,到底要不要自己的框架??
- 如何通过iTunes安装ipa测试包
- 红帽子linux命令界面,红帽子_Linux_命令全解
- Windows电脑如何查看内存条配置
- How to Reassign Workflow Task in Sharepoint 2007
- 坚持自主可控,长安链ChainMaker全面拥抱国密的技术实践
- 做中国的Salesforce,神州云动凭的是什么?
热门文章
- Oracle 练习题 20131021 for 循环练习
- VB.NET判断一个路径的文件是否存在
- 华为交换机S3700-TELNET远程管理交换机配置
- 简易数字时钟软件详细制作过程
- 对一道基础string题及其变式题的思考与解析
- vite + vue2 + eslint 项目配置
- python都有哪些包装_Python基础:21包装
- rc时间常数公式_你知道RC电路和RL电路中时间常数的来源以及和时间的关系吗?...
- 建筑与计算机技术,建筑设计中常用的计算机技术与注意点
- java借口案例实现_java实现接口的典型案例