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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

c理c利用计算机怎么弹,通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的...

發(fā)布時(shí)間:2025/3/11 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 c理c利用计算机怎么弹,通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的... 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

通過匯編一個(gè)簡(jiǎn)單的C程序,分析匯編代碼理解計(jì)算機(jī)是如何工作的

計(jì)算機(jī)的工作方式:

現(xiàn)代計(jì)算機(jī)的基本體系結(jié)構(gòu)都是采用馮諾依曼結(jié)構(gòu),馮諾依曼的設(shè)計(jì)思想最重要之處是"存儲(chǔ)程序"的這個(gè)概念。計(jì)算機(jī)的工作過程,就是執(zhí)行程序的過程。首先編寫需要執(zhí)行的程序,然后通過輸入設(shè)備送到存儲(chǔ)器保存起來(lái),即程序存儲(chǔ)。根據(jù)馮諾依曼的設(shè)計(jì),計(jì)算機(jī)應(yīng)能自動(dòng)執(zhí)行程序,而執(zhí)行程序又歸結(jié)為逐條執(zhí)行指令。執(zhí)行一條指令又可分為以下4個(gè)基本操作:取出指令:從存儲(chǔ)器某個(gè)地址中取出要執(zhí)行的指令送到CPU內(nèi)部的指令寄存器暫存。

分析指令:把保存在指令寄存器中的指令送到指令譯碼器,譯出該指令對(duì)應(yīng)的微操作。

執(zhí)行指令:根據(jù)指令譯碼,向各個(gè)部件發(fā)出相應(yīng)控制信號(hào),完成指令規(guī)定的各種操作。

為執(zhí)行下一條指令作好準(zhǔn)備,即取出下一條指令地址。

接下來(lái)通過一個(gè)簡(jiǎn)單的c程序來(lái)分析一下,程序的執(zhí)行過程

這里是一個(gè)非常簡(jiǎn)單的c程序,源代碼如下:

輸入:gcc S o main.s main.c m32 來(lái)生成匯編代碼

整潔一下匯編代碼以后,查看匯編代碼:

我在我的虛擬機(jī)中的ubuntu系統(tǒng)與實(shí)驗(yàn)樓ubuntu系統(tǒng)的匯編代碼有點(diǎn)不一樣

下面通過gdb單步執(zhí)行來(lái)分析棧上寄存器的情況:

首先我們從main函數(shù)開始。(前兩條語(yǔ)句在gdb執(zhí)行時(shí)設(shè)置不了斷點(diǎn),但是執(zhí)行函數(shù)的語(yǔ)句都有這2條,放到其他函數(shù)來(lái)說(shuō)明):

在main函數(shù)上先設(shè)置一個(gè)斷點(diǎn),然后運(yùn)行:

此時(shí)查看寄存器的值:

他們的值:esp和ebp都是0xbffff568,eip是0x8048409(正好是下一條要執(zhí)行的指令的地址)

接下來(lái)繼續(xù)執(zhí)行:

把2壓到棧上

此時(shí),esp的減4了,而ebp不變,eip繼續(xù)指向下一條指令

下一條要執(zhí)行call指令,這里再對(duì)函數(shù)f設(shè)置一個(gè)斷點(diǎn),繼續(xù)執(zhí)行:

此時(shí),程序跳到函數(shù)f中去了

call ?f

調(diào)用函數(shù) f,其實(shí)這條指令等價(jià)于

pushl %eip

movl ?$f, %eip

eip的值被保存在esp-4的位置上,保存eip的目的是函數(shù)調(diào)用返回時(shí)能夠繼續(xù)執(zhí)行call f下面的語(yǔ)句:

此時(shí),esp的值為0xbffff560,ebp都是0xbffff568

跳轉(zhuǎn)到函數(shù)f后,前兩條語(yǔ)句和 main 函數(shù)相同,都是保存堆棧狀態(tài),這里詳細(xì)來(lái)說(shuō)明一下:

先把ebp的值保存咋esp-4的位置上

再把esp的值賦給sbp,此時(shí)esp和ebp的值都為0xbffff55c

然后繼續(xù)執(zhí)行,把ebp+8的內(nèi)容即2這個(gè)值壓棧:

此時(shí)esp繼續(xù)-4

查看寄存器的值

寄存器的值:esp的值為0xbffff558,ebp的值為0xbffff55c,

接下來(lái)要跳轉(zhuǎn)到函數(shù)g了,因此再對(duì)函數(shù)g設(shè)置一個(gè)斷點(diǎn),然后繼續(xù)執(zhí)行:

觀察寄存器的值:

同理:寄存器eip的值繼續(xù)被保存了在esp-4的位置上,以便能夠返回到函數(shù)f

進(jìn)入g函數(shù)老的ebp的值也被保存了,新的esp和ebp相同

此時(shí),esp和ebp的值都是0xbffff550

接下來(lái)繼續(xù)執(zhí)行,把ebp+8的值給eax

查看寄存器,此時(shí)esp和ebp的值都是0xbffff550,eax的值是2

繼續(xù)執(zhí)行:

把3和eax的值相加結(jié)果再保存到eax中

查看寄存器

寄存器eax的值變成5了,esp和ebp的值都是0xbffff550

然后繼續(xù)執(zhí)行:

把esp指向的值給ebp,查看寄存器

寄存器的值:esp的值為0xbffff554,ebp的值0xbffff55c,eax還是5

然后繼續(xù)執(zhí)行:

指令ret相當(dāng)于指令popl %eip

esp的值為0xbffff558,ebp的值0xbffff55c,eax還是5

這樣又返回到函數(shù)f繼續(xù)執(zhí)行:

繼續(xù)執(zhí)行,然后查看寄存器:

Esp和ebp的值都是0xbffff55c,eax還是5

繼續(xù)執(zhí)行,leave,這條指令相當(dāng)于下面兩條指令:

movl ?%ebp, %esp

popl ?%ebp

查看寄存器

esp的值為0xbffff560,ebp的值0xbffff568,eax還是5

繼續(xù)執(zhí)行ret,彈出保存的eip的值,返回到main函數(shù)執(zhí)行:

查看寄存器的值,esp的值為0xbffff564,ebp的值0xbffff568,eax還是5

連續(xù)執(zhí)行2步,繼續(xù)執(zhí)行

此時(shí)eax的值變成了6,esp和ebp的值0xbffff568

然后繼續(xù)執(zhí)行2步,main函數(shù)就返回了

總結(jié)

通過分析對(duì)應(yīng)的匯編代碼和觀察運(yùn)行棧的變化,加深了對(duì)程序執(zhí)行過程的了解,也明白了計(jì)算機(jī)的工作方式:根據(jù)eip 指指令執(zhí)行,同時(shí)eip自增;

如果執(zhí)行的是跳轉(zhuǎn)語(yǔ)句時(shí),先把eip壓棧,然后將需要跳轉(zhuǎn)的目的地址賦給 eip,實(shí)現(xiàn)跳轉(zhuǎn);

若執(zhí)行函數(shù)調(diào)用時(shí),將 eip 壓棧,同時(shí)將ebp壓棧,然后將相應(yīng)函數(shù)地址賦給 eip;

若為其他指令,則繼續(xù)從 eip 指向的地址取指令執(zhí)行。

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的c理c利用计算机怎么弹,通过汇编一个简单的C程序,分析汇编代码理解计算机是如何工作的...的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。