彙編的藝術(01)sizeof operator

2022-09-16 00:36:07 字數 1327 閱讀 9189

學習彙編對於我自己的感覺是:可以從更加底層的角度來窺視c語言以及其他高層語言的細節。這是一件很舒服的事情~

同時一些特殊的工作,比如核心除錯,記憶體錯誤,函式呼叫等問題,用彙編的角度來看待會更加方便,更加深刻的理解其機制。

廢話不多說,作為開篇《彙編的藝術》,是我今天更巧碰到的乙個問題,想記下來,先從最簡單的入手,感覺是慢慢來的~

先看一段**:

int

main()

出乎意料的是,輸出的值是:1,-1

難道是sizeof裡面的++a沒有執行麼?帶著這樣的疑問,看看反彙編**是啥樣的:

int

main()

0000005c mov eax,dword ptr [ebp-4

] 0000005f mov esp,ebp

00000061

pop ebp

00000062 ret

看到橙黃色標註的部分,果然傳參的時候是直接push了1,而++a這個指令在沒有在彙編**現的痕跡。

但是sizeof操作符並不像#define這樣的巨集一樣在預處理階段就把其替換掉了,sizeof是在編譯階段替換的。

於是理解了,sizeof裡面的expression都是不執行的,只關心裡面型別的大小。

類似的問題還有sizeof('a'),貌似不同的編譯器說法不一,c標準應該是把'a'看成了97,也就是int型別,等於4,

如果裡面的數字再大的話,超過了int範圍,則是8了,以此類推。

還有是sizeof("a"),這個問題不該有爭議,因為傳進去的是字串a的位址,就是乙個指標的大小了,32位機器上面是4,64位機器上面應該是8.

btw:

很久沒有看過反彙編**了,很多東西都生疏了。

比如說裡面不理解的是,main()函式明明只申請了乙個char 的卻把棧空間抬高了8個位元組,邊界對齊為char開闢4位元組還能理解。

那另外的4個位元組又是什麼意思呢?函式最後返回的**利用到了這4個位元組,把裡面的值傳給eax。

這是彙編的風格,函式的返回值是傳給eax的。但是不清楚為什麼還要「多此一舉」。

我的理解是,因為函式最終要返回的,對於一般的函式如果返回比如 return ans; ans變數肯定要開闢位元組空間的,於是return 0; 也按照這個思路照做了?有時間再**。

第二個問題就是又一次的複習了函式傳參時堆疊的情況。感覺都有點生疏了。

printf 第乙個引數壓入的是格式化字串的位址,後面壓入的幾個引數則是變數。對於這類引數可變的函式,平衡堆疊的工作要交給母函式來處理的。

關於這方面詳細的介紹請看:

彙編檔案 s和 S的區別

s 組合語言源程式 操作 彙編 s組合語言源程式 操作 預處理 彙編 1.小寫的 s檔案,在後期階段不會再進行預處理操作了,所以我們不能在其內寫上預處理語句。一般是 c 檔案經過彙編器處理後的輸出。如 gcc 編譯器就可以指定 s 選項進行輸出,且是經過預處理器處理後 的了。2.大寫的 s 檔案,還...

source insight支援 S的彙編檔案

用source insight看blob以及核心中的 發現即使全域性搜尋,也找不到定義中字尾為.s的函式,而明明在 s中用彙編定義了該函式的。去網上查了一下,發現原因是 s檔案並沒有新增到改工程中來。為了用source insight能搜尋到.s的彙編檔案,必須把該檔案新增進來。方法 1 在建立工程...

source insight支援 S的彙編檔案

用source insight看blob以及核心中的 發現即使全域性搜尋,也找不到定義中字尾為.s的函式,而明明在 s中用彙編定義了該函式的。去網上查了一下,發現原因是 s檔案並沒有新增到改工程中來。為了用source insight能搜尋到.s的彙編檔案,必須把該檔案新增進來。方法 1 在建立工程...