大家先看一下這段程序:
[cpp]
#include <stdio.h>
typedef unsigned char bool;
typedef struct _person person;
struct _person {
bool sex;
};
person main() {
person xingwang;
xingwang.sex = 0;
return xingwang;
}
如此簡單清晰的程序,您覺得會報錯嗎?如果您和我一樣,感覺肯定不會報錯,請繼續看這段程序編譯以後的匯編代碼:
[plain]
.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。