曹摯
摘 要:匯編語言是和機(jī)器語言一一對(duì)應(yīng)的一種符號(hào)語言。通過匯編語言能夠看到程序執(zhí)行的全過程。通過查看高級(jí)語言(這里以C語言為例)對(duì)應(yīng)的匯編語句,可以更加深入地理解程序的執(zhí)行步驟。本文通過一個(gè)C語言表達(dá)式的例子來說明利用匯編指令能夠解釋C語言中晦澀難懂的語句的執(zhí)行過程。
關(guān)鍵詞:匯編語言;機(jī)器語言;符號(hào)語言;高級(jí)語言
一、引言
在C語言的學(xué)習(xí)過程中,不同的讀者會(huì)使用不同的編譯器進(jìn)行程序的運(yùn)行和調(diào)試,不同的C語言編譯器由于開放廠商不同,對(duì)于C語言的某些晦澀難懂的表達(dá)式產(chǎn)生不同的結(jié)果。盡管這些問題只占C語言學(xué)習(xí)過程中的小部分,但是對(duì)于C語言的初學(xué)者來說會(huì)有學(xué)習(xí)障礙并產(chǎn)生畏難情緒。目前很多編譯器都有一個(gè)反匯編功能。這里的反匯編特指將C程序源代碼反向編譯成匯編語言的代碼。由于匯編語言和機(jī)器語言是一一對(duì)應(yīng)的,因此通過匯編語言能夠看到對(duì)應(yīng)的C語言代碼在機(jī)器中的運(yùn)行全過程,這個(gè)過程僅僅通過C程序代碼來看是不夠清晰的。本文以一個(gè)表達(dá)式的例子來說明反匯編后的語句能夠解釋C代碼中的疑難問題。特別說明的是這里需要讀者對(duì)匯編語言有簡單的了解。
二、匯編語言與高級(jí)語言
計(jì)算機(jī)能夠識(shí)別的只有二進(jìn)制的機(jī)器指令,然而由于機(jī)器指令繁瑣且難懂,因此產(chǎn)生了一種符號(hào)語言即匯編語言。匯編語言用一些常見的英文字母和數(shù)據(jù)表示一個(gè)指令,同時(shí)匯編語言中的匯編指令與機(jī)器指令是一一對(duì)應(yīng)的,而目前流行的高級(jí)語言是做不到的。匯編語言是機(jī)器語言的助記符,在各種計(jì)算機(jī)語言中,除了機(jī)器語言,匯編語言是執(zhí)行速度最快的語言,所占的內(nèi)存空間也很小。匯編語言曾經(jīng)是非常流行的程序設(shè)計(jì)語言,但是隨著軟件規(guī)模的不斷增長,人們對(duì)于軟件開發(fā)的進(jìn)度和效率的要求越來越高,匯編語言顯得有些力不從心,高級(jí)語言就逐漸代替了匯編語言。匯編語言的應(yīng)用逐漸轉(zhuǎn)向了嵌入式領(lǐng)域和工業(yè)控制領(lǐng)域。但是高級(jí)語言并不能完全代替匯編語言,匯編語言能夠最大限度地發(fā)揮硬件的性能。
我們經(jīng)常接觸的C語言、C++語言、Java語言、C#語言都屬于高級(jí)語言的范疇,高級(jí)語言和機(jī)器語言有一定的鴻溝,它屬于偏向人類自然語言的一種計(jì)算機(jī)語言。高級(jí)語言中的語句類似于數(shù)學(xué)表達(dá)式,人們更加容易理解,因此高級(jí)語言成為了目前主流的計(jì)算機(jī)語言。尤其是近些年來,面向?qū)ο蟮乃枷肽軌蚋訙?zhǔn)確地模擬了自然界的行為,因此面向?qū)ο蟮母呒?jí)語言(如C++、Java、C#)成為了軟件設(shè)計(jì)的主流語言。
三、一個(gè)例子
這里舉一個(gè)C語言的例子,程序輸出由三個(gè)自增運(yùn)算符相加后的結(jié)果。運(yùn)行的環(huán)境是VC++6.0。這里有必要說明的是,該語句在不同的編譯器下面可能會(huì)產(chǎn)生不同的結(jié)果。而對(duì)于不同結(jié)果的解釋則要通過將C語言轉(zhuǎn)換成對(duì)應(yīng)的匯編語言才能夠解釋清楚。限于篇幅,這里只將程序的核心語句列出:
int i = 1; int s; s = (++i) + (++i) + (++i); printf("%d\n", s);
很多初學(xué)者看到這個(gè)表達(dá)式,不假思索地就會(huì)得出6,因?yàn)樗麄冋J(rèn)為i初始值為1,自增后都為2,因此結(jié)果為6。還有一部分人想得深入一些,他們認(rèn)為編譯器會(huì)先計(jì)算第一個(gè)++i,i自增以后為2,然后計(jì)算第二個(gè)++i,自增后i的值是3,最后計(jì)算第三個(gè)++i,得到4,計(jì)算2+3+4值為9。這種想法看似合理,然而通過編譯器VC++6.0運(yùn)行后的結(jié)果是10。這個(gè)結(jié)果讓人無法理解,這里只有通過該表達(dá)式對(duì)應(yīng)的匯編語言才能解釋清楚。通過VC++6.0中的反編譯工具,得到了語句s = (++i) + (++i) + (++i)所對(duì)應(yīng)的匯編語言如下:
mov ecx, dword ptr[ebp-8]
add ecx, 1
mov dword ptr [ebp-8], ecx
mov edx, dword ptr [ebp-8]
add edx, 1
mov dword ptr [ebp-8], edx
mov eax, dword ptr [ebp-8]
add eax, dword ptr [ebp-8]
mov ecx, dword ptr [ebp-8]
add ecx, 1
mov dword ptr [ebp-8], ecx
add eax, dword ptr [ebp-8]
mov dword ptr [ebp-0Ch], eax
從對(duì)應(yīng)的匯編語言中可以看出,VC++對(duì)該語言進(jìn)行了優(yōu)化。先算的是前兩個(gè)++i,即此時(shí)i的值為3,前后兩個(gè)i都為3。然后相加后再計(jì)算第三個(gè)++i,此時(shí)i的值為4,這樣最后的結(jié)果就是3+3+4的和為10,和程序運(yùn)行后的結(jié)果一致。這里體現(xiàn)出了匯編的思維,而不僅僅是用C語言的語法來解釋。
四、總結(jié)與展望
通過前面的例子可以看出,在學(xué)習(xí)C語言之前,適當(dāng)了解一些匯編語言的語法和計(jì)算機(jī)底層硬件的知識(shí)是大有好處的,因?yàn)閰R編語言和機(jī)器語言能夠做到一一對(duì)應(yīng),而高級(jí)語言則無法做到,因此將高級(jí)語言(如C語言)通過編譯器轉(zhuǎn)化成匯編語言,可以清晰地看到程序在機(jī)器上的運(yùn)轉(zhuǎn)過程。對(duì)于程序中含義模糊的語句就可以一目了然了。通過上面的例子也可以看出,學(xué)習(xí)C語言最好要有點(diǎn)匯編語言的思維,C語言里面晦澀難懂的語句可以通過其對(duì)應(yīng)的匯編語言來解釋。另外學(xué)習(xí)匯編語言可以讓你真正了解計(jì)算機(jī),理解高級(jí)語言的本質(zhì)與真諦。對(duì)于一個(gè)全面了解微機(jī)原理的程序員,匯編語言是必修語言。