作者GNUGCC (-std=c++14)
看板C_and_CPP
标题Fw: [问题] 呼叫gets前的sub $0xc,%esp
时间Thu Jul 28 14:52:38 2016
※ [本文转录自 ASM 看板 #1NcQiseh ]
作者: GNUGCC (-std=c++14) 看板: ASM
标题: [问题] 呼叫gets前的sub $0xc,%esp
时间: Thu Jul 28 14:50:28 2016
小弟最近在练习看组语,遇到问题想来请教各位
这是source code
#include <stdlib.h>
#include <stdio.h>
void print(){
char buf[5];
gets(buf);
}
int main(){
print();
}
这是在
ubuntu 16.04 amd64
用
gcc -fno-stack-protector -m32 -O0 test.c
编译出来的结果
0804840b <print>:
804840b: 55 push %ebp
804840c: 89 e5 mov %esp,%ebp
804840e: 83 ec 18 sub $0x18,%esp <=为啥预留24 bytes
8048411: 83 ec 0c sub $0xc,%esp <=为啥要减12
8048414: 8d 45 f3 lea -0xd(%ebp),%eax
8048417: 50 push %eax
8048418: e8 c3 fe ff ff call 80482e0 <gets@plt>
804841d: 83 c4 10 add $0x10,%esp
8048420: 90 nop
8048421: c9 leave
8048422: c3 ret
我的问题有两个
(1)
我明明只宣告buf[5]的local variable
我觉得只会预留8 bytes,为甚麽gcc却帮我预留了24 bytes
(2)
为啥在呼叫gets前会出现
sub $0xc,%esp
这个指令有什麽作用?
-----------------补充--------------------
这是对照组,没有呼叫gets的版本
#include <stdlib.h>
#include <stdio.h>
void print(){
char buf[5];
}
int main(){
print();
}
080483db <print>:
80483db: 55 push %ebp
80483dc: 89 e5 mov %esp,%ebp
80483de: 83 ec 10 sub $0x10,%esp <=这边也留了16 bytes
80483e1: 90 nop
80483e2: c9 leave
80483e3: c3 ret
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.113.186.243
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/ASM/M.1469688630.A.A2B.html
※ 发信站: 批踢踢实业坊(ptt.cc)
※ 转录者: GNUGCC (140.113.186.243), 07/28/2016 14:52:38
1F:→ GNUGCC: 因为和C稍微有关系,而且这边人比较多,所以转过来,请板 07/28 14:55
2F:→ GNUGCC: 主包容,谢谢! 07/28 14:57
3F:推 longlongint: 1 配四的倍数 是为了配合硬体(? 07/28 14:57
因为我宣告buf[5],所以配四个倍数,我觉得应该要是8
4F:→ longlongint: 2 分配区域变数的空间 07/28 14:58
如果是分配gets的区域变数,那不是会在gets里面才减吗?
5F:→ longlongint: 根据记忆回的 我觉得你查一下书里面应该有写 07/28 14:59
※ 编辑: GNUGCC (140.113.186.243), 07/28/2016 15:02:43
6F:→ longlongint: 突然想到还有个传参数功能 07/28 15:04
7F:→ longlongint: 还有存ip忘了说 07/28 15:04
8F:→ longlongint: 还有一个功能是存ebp...... 07/28 15:10
9F:→ wtchen: 板工勉强放行,至少言之有物 07/28 15:15
10F:推 longlongint: 我也不懂为什麽要减16这个数字 XD 07/28 15:31
d大正解
我改用gcc -fno-stack-protector -m32 -O0 -mpreferred-stack-boundary=2 test.c
奇怪的东西都消失了
0804840b <print>:
804840b: 55 push %ebp
804840c: 89 e5 mov %esp,%ebp
804840e: 83 ec 08 sub $0x8,%esp
8048411: 8d 45 fb lea -0x5(%ebp),%eax
8048414: 50 push %eax
8048415: e8 c6 fe ff ff call 80482e0 <gets@plt>
804841a: 83 c4 04 add $0x4,%esp
804841d: 90 nop
804841e: c9 leave
804841f: c3 ret
感谢d大
※ 编辑: GNUGCC (140.113.186.243), 07/28/2016 15:51:25
12F:→ x000032001: 应该是为了对齐16bytes 07/28 20:47
13F:推 LPH66: 原 PO 在问的就是为什麽是 16 byte, 其原因就是那个选项 07/28 23:10
14F:推 longlongint: 哇 学习了 07/29 00:39
15F:推 Sidney0503: ID wwwwwwwwww 07/30 18:31