簡體   English   中英

為什么我的機器在這段代碼中將堆棧指針減少了 20?

[英]Why is the my machine decrease the stack pointer by 20 in this code?

我用 GCC 編譯了以下 C 代碼,並在 gdb 中反匯編為匯編。 我使用的是配備 64 位 Intel i5 處理器的 Macbook pro。 在 'main()' 中,'char* name[2]' 有 2 個字符指針,應該讓堆棧指針減少 2 個字(16 字節)? 但是,當我在 gdb 中反匯編時它減少了 20 ......有人可以幫助我理解嗎? 代碼:

#include <stdio.h>
#include <unistd.h>
int main(void)
{   
    char* name[2];
    name[0] = "/bin/sh";
    name[1]= NULL;
    execve(name[0],name,NULL);
}

gdb反匯編代碼:

GNU gdb 6.3.50-20050815 (Apple version gdb-1708) (Thu Nov  3 21:59:02 UTC 2011)
Copyright 2004 Free Software Foundation, Inc.
GDB is free software, covered by the GNU General Public License, and you are
welcome to change it and/or distribute copies of it under certain conditions.
Type "show copying" to see the conditions.
There is absolutely no warranty for GDB.  Type "show warranty" for details.
This GDB was configured as "x86_64-apple-darwin"...Reading symbols for shared libraries .. done

(gdb) disassemble main
Dump of assembler code for function main:
0x0000000100000ee0 <main+0>:    push   %rbp
0x0000000100000ee1 <main+1>:    mov    %rsp,%rbp
0x0000000100000ee4 <main+4>:    sub    $0x20,%rsp
0x0000000100000ee8 <main+8>:    lea    -0x18(%rbp),%rax
0x0000000100000eec <main+12>:   lea    0x61(%rip),%rcx        # 0x100000f54
0x0000000100000ef3 <main+19>:   mov    %rcx,-0x18(%rbp)
0x0000000100000ef7 <main+23>:   movq   $0x0,-0x10(%rbp)
0x0000000100000eff <main+31>:   mov    -0x18(%rbp),%rcx
0x0000000100000f03 <main+35>:   mov    $0x0,%rdx
0x0000000100000f0d <main+45>:   mov    %rcx,%rdi
0x0000000100000f10 <main+48>:   mov    %rax,%rsi
0x0000000100000f13 <main+51>:   callq  0x100000f22 <dyld_stub_execve>
0x0000000100000f18 <main+56>:   mov    -0x4(%rbp),%eax
0x0000000100000f1b <main+59>:   add    $0x20,%rsp
0x0000000100000f1f <main+63>:   pop    %rbp
0x0000000100000f20 <main+64>:   retq   
End of assembler dump.

因此,讀取程序集時,名稱[0] 位於堆棧中的 -0x18,名稱1位於 -0x10。 此外,如前所述,-0x4 用於返回值。

剩下 12 個字節,因為 0x20 實際上是 32。范圍 -32 到 -24 和范圍 -8 到 -4。 -8 到 -4 肯定是對齊的,我猜 -32 到 -24 也是如此(對於 16 字節對齊)。

編輯:請注意,實際上減去了 48 個字節。 調用 main 的 callq 指令從 RSP 中減去 8 個字節, push %rbp 8 個字節。

經驗證的 16 字節對齊: x86-64 System V ABI第 3.2.2 節(直接鏈接到舊版本的 PDF

我猜想這種“奇怪的”堆棧幀格式與“延遲綁定”調用約定有關,顯然在您的調用中使用了這種約定。 即您實際上是在調用延遲綁定存根dyld_stub_execve ,而不是execve本身。 調用后從-0x4(%rbp)讀取的結果代碼可能是綁定不成功時返回的錯誤代碼。

如果您靜態鏈接庫,我猜為調用准備的堆棧幀看起來會更傳統。

PS 我的回答可能純屬無稽之談,因為堆棧幀形成代碼是在正確編譯期間生成的,而使用靜態或共享庫的決定僅在鏈接時做出。

如果你說的是<main+4> ,它不是減去 20(以 10 為底)。 它在基數 16 中減去 20,即16^1 * 2 + 16^0 * 0 ,等於 32,或 2 個單詞的大小。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM