日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

汇编的艺术(01)sizeof operator

發布時間:2023/12/13 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 汇编的艺术(01)sizeof operator 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

以前在百度的博客里面學習了逆向一些基本的C語言知識。一方面不能讓學習的匯編知識荒廢,另外一方面是由于經常碰到一些細節性的問題,需要溫故而知新。

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

同時一些特殊的工作,比如內核調試,內存錯誤,函數調用等問題,用匯編的角度來看待會更加方便,更加深刻的理解其機制。

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

先看一段代碼:

int main() { char a = 255; printf("%d\n",sizeof(++a)); printf("%d\n",a); return 0; }

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

難道是sizeof里面的++a沒有執行么?帶著這樣的疑問,看看反匯編代碼是啥樣的:

int main() { char a = 255; 00000000 push ebp 00000001 mov ebp,esp 00000003 sub esp,8 00000006 cmp dword ptr ds:[00192E14h],0 0000000d je 00000014 0000000f call 696E67F9 00000014 xor edx,edx 00000016 mov dword ptr [ebp-4],edx 00000019 mov dword ptr [ebp-8],0 00000020 xor edx,edx 00000022 mov dword ptr [ebp-4],edx 00000025 mov dword ptr [ebp-8],0FFFFFFFFh printf("%d\n",sizeof(++a)); 0000002c push 1B31B8h 00000031 push 1 00000033 push 4F01B8h 00000038 call FEEA58CC 0000003d add esp,0Ch 00000040 nop printf("%d\n",a); 00000041 push 1B31BCh 00000046 push dword ptr [ebp-8] 00000049 push 4F01C8h 0000004e call FEEA58CC 00000053 add esp,0Ch 00000056 nop return 0; 00000057 xor edx,edx 00000059 mov dword ptr [ebp-4],edx } 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 的卻把??臻g抬高了8個字節,邊界對齊為char開辟4字節還能理解。

那另外的4個字節又是什么意思呢?函數最后返回的代碼利用到了這4個字節,把里面的值傳給eax。

這是匯編的風格,函數的返回值是傳給eax的。但是不清楚為什么還要“多此一舉”。

我的理解是,因為函數最終要返回的,對于一般的函數如果返回比如 return ans; ans變量肯定要開辟字節空間的,于是return 0; 也按照這個思路照做了?有時間再探究。

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

printf 第一個參數壓入的是格式化字符串的地址,后面壓入的幾個參數則是變量。對于這類參數可變的函數,平衡堆棧的工作要交給母函數來處理的。

關于這方面詳細的介紹請看:http://bbs.pediy.com/showthread.php?t=56518

轉載于:https://www.cnblogs.com/kedebug/archive/2012/12/03/2800225.html

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的汇编的艺术(01)sizeof operator的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。