大家先看一下這段程序:
- #include <stdio.h>
-
- typedef unsigned char bool;
- typedef struct _person person;
-
- struct _person {
- bool sex;
- };
-
- person main() {
-
- person xingwang;
- xingwang.sex = 0;
-
- return xingwang;
- }
如此簡單清晰的程序,您覺得會報錯嗎?如果您和我一樣,感覺肯定不會報錯,請繼續看這段程序編譯以後的匯編代碼:
- .file "struct.c"
- .text
- .globl main
- .type main, @function
- main:
- pushl %ebp
- movl %esp, %ebp
- subl $16, %esp
- movl 8(%ebp), %eax
- movb $0, -1(%ebp)
- movzbl -1(%ebp), %edx
- movb %dl, (%eax)
- leave
- ret $4
- .size main, .-main
- .ident "GCC: (GNU) 4.4.6 20110731 (Red Hat 4.4.6-3)"
- .section .note.GNU-stack,"",@progbits
pushl %ebp 將當前的基址存儲,函數退出時用
movl %esp, %ebp 當前函數的基址
subl $16, %esp 在棧中,分配16個字節來存儲局部的變量
movl 8(%ebp), %eax 調用main()函數的地方,返回值會存儲在這裡。(很顯然,沒有函數調用main(),這個地址很不確定)
movb $0, -1(%ebp) 為xingwang.sex賦值
movzbl -1(%ebp), $edx
movb %dl, (%eax) 將xingwang賦值給eax指向的內存地址
問題就出在 movl 8(%ebp), %eax 這一行。使用GDB調試以後發現,%ebp+8這個位置的值是 0x1,也就是說函數最後的返回值要存儲給0x1這個內存單元。很顯然這個內存單元不是用戶可以操作的。
所以,這個C程序最後運行時,會提示 段錯誤 或者 Segment Fault。