Fw: [問題] 呼叫gets前的sub $0xc,%esp

看板C_and_CPP作者 (-std=c++14)時間7年前 (2016/07/28 14:52), 7年前編輯推噓5(5010)
留言15則, 7人參與, 最新討論串1/1
※ [本文轉錄自 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://www.ptt.cc/bbs/ASM/M.1469688630.A.A2B.html ※ 發信站: 批踢踢實業坊(ptt.cc) ※ 轉錄者: GNUGCC (140.113.186.243), 07/28/2016 14:52:38

07/28 14:55, , 1F
因為和C稍微有關係,而且這邊人比較多,所以轉過來,請板
07/28 14:55, 1F

07/28 14:57, , 2F
主包容,謝謝!
07/28 14:57, 2F

07/28 14:57, , 3F
1 配四的倍數 是為了配合硬體(?
07/28 14:57, 3F
因為我宣告buf[5],所以配四個倍數,我覺得應該要是8

07/28 14:58, , 4F
2 分配區域變數的空間
07/28 14:58, 4F
如果是分配gets的區域變數,那不是會在gets裡面才減嗎?

07/28 14:59, , 5F
根據記憶回的 我覺得你查一下書裡面應該有寫
07/28 14:59, 5F
※ 編輯: GNUGCC (140.113.186.243), 07/28/2016 15:02:43

07/28 15:04, , 6F
突然想到還有個傳參數功能
07/28 15:04, 6F

07/28 15:04, , 7F
還有存ip忘了說
07/28 15:04, 7F

07/28 15:10, , 8F
還有一個功能是存ebp......
07/28 15:10, 8F

07/28 15:15, , 9F
板工勉強放行,至少言之有物
07/28 15:15, 9F

07/28 15:31, , 10F
我也不懂為什麼要減16這個數字 XD
07/28 15:31, 10F

07/28 15:33, , 11F
q2: http://goo.gl/vNJXig, -mpreferred-stack-boundary
07/28 15:33, 11F
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

07/28 20:47, , 12F
應該是為了對齊16bytes
07/28 20:47, 12F

07/28 23:10, , 13F
原 PO 在問的就是為什麼是 16 byte, 其原因就是那個選項
07/28 23:10, 13F

07/29 00:39, , 14F
哇 學習了
07/29 00:39, 14F

07/30 18:31, , 15F
ID wwwwwwwwww
07/30 18:31, 15F
文章代碼(AID): #1NcQktZT (C_and_CPP)