1. 程式人生 > >你很燙嗎?我很燙

你很燙嗎?我很燙

在上一篇文章中,我們逆向了Debug模式下的一個C程式,發現棧區開闢的儲存空間都是使用0CCCCCCCCh來填充4位元組單位的,也就是說,棧區開闢的存取區域性變數的空間的每一個位元組都被0xCC填充了。(為什麼用0xCC,這個是int 3h的機器碼,下斷點用的)兩個0xCC合起來輸出時恰好對應中文“燙”字。
這也就不奇怪程式輸出那麼多“燙”了。
——————–紙上得來終覺淺,絕知此事要躬行——————–
例項一:

1234567891011 // 如果不建立工程,請大家自己修改一下標頭檔案#include "stdafx.h"#include <string.h>int_tmain(intargc,_TCHAR*argv[]){chars[256]={0};// 定義一個數組memset(s,0xCC,sizeof(s));// 用0xCC填充printf("%s\n",s);// 輸出return1;}

大家可以自己檢視執行結果:

程式輸出很多燙字

程式輸出結果

例項二:

12345678910 // 如果不建立工程,請大家自己修改一下標頭檔案#include "stdafx.h"#include <string.h>int_tmain(intargc,_TCHAR*argv[]){chars[256];// 系統預設用0xCC填充printf("%s\n",s);// 輸出return1;}

程式輸出還是”很燙“。

例項三:把字元陣列定義為全域性變數

1234567891011 // 如果不建立工程,請大家自己修改一下標頭檔案#include "stdafx.h"#include <string.h>chars[256];// 全域性變數int_tmain(intargc,_TCHAR*argv[]){printf("%s\n",s);// 輸出return1;}

這次系統輸出了空,沒有燙了!為什麼,請讀者自己思考。

其實,全域性變數分配在”全域性/靜態儲存區“中,區域性變數分配在棧中,我們可以定義一個很大的陣列,如果是區域性的,會導致程式棧溢位,因為棧的空間大小是有限制的;而全域性的則不會。

另外需要注意,這些”燙燙燙燙燙燙燙“現象只會在Debug模式中出現,在Release模式中不會出現。

如果你對”燙燙燙燙燙燙燙“表示很熟悉,那麼”屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯屯“你見過嗎?應該吧。我本人以前經常遇到”燙“,但很少遇到後者。

例項四:動態分配記憶體空間

123456789101112 // 如果不建立工程,請大家自己修改一下標頭檔案#include "stdafx.h"#include <stdio.h>#include <stdlib.h>intmain(intargc,char*argv[]){char*s=(char*)malloc(sizeof(char)*256);puts(s);free(s);return0;}

執行程式,頓時滿屏的”屯“字出現在眼前,有圖有真相:

程式輸出很多屯字

程式輸出結果

因為,動態分配的空間開闢與堆,VC的Debug用0xCD填充堆的空間,兩個0xCD和在一起就是屯了。

試著去反彙編跟蹤了一下,實在是跳來跳去麻煩,放棄了。

本文涉及到的中文編碼與變數存放位置並沒有詳細講解,讀者請自己查閱相關資料。