深入理解電腦系統(3.1)---走進彙編的世界

來源:互聯網
上載者:User

標籤:

 

本文轉載地址:http://www.cnblogs.com/zuoxiaolong/p/computer13.html

 

為何要學習組合語言

 

  對於大部分猿友來說,平時寫的都是一些進階程式設計語言,是電腦領域的諸多大神,經過幾層的封裝才讓我們享有了這樣的待遇。這樣一來,我們在平時的開發過程中,可以省去很多底層的麻煩。試想一下,倘若在你寫一個方法的時候,你還需要去操心哪些變數需要放在寄存器,哪些變數放在主存,放在寄存器的話又該放在哪一個裡面,放在主存的話又該放在那個記憶體地區等等這一類底層的問題,以及還要去記各種各樣的寄存器名稱和它們的作用等等諸如此類的事,你是否會崩潰呢。

  因此這不難看出,進階語言給我們帶來了很多便捷,但是事情總不是十全十美的,這樣所帶來的便捷也同時引來了一些問題。這是因為我們看到的代碼,在實際執行它們的時候,可能已經面目全非了,所以很多時候會造成一些莫名其妙的問題發生。

  舉一個小例子,LZ曾經在群裡問過類似的問題,這次LZ寫一個小程式,各位學過Java的猿友來看看這個程式的結果。

public class Main{  public static void main(String[] args)  {      Integer a = 127;      Integer b = 127;      Integer c = 128;      Integer d = 128;      System.out.println(a == b);      System.out.println(c == d);  }  }

  相信有不少人看不出來這個程式的問題在哪,覺得應該輸出兩個true就對了。可是這個程式的結果卻是一個true和一個false,如果哪位猿友不信的話可以自己試一下。至於原因是什麼,各位有興趣的可以去研究下Java的自動拆裝箱,另外再看一下Integer對象的valueOf方法緩衝的範圍,答案就會自動揭曉。

  產生這個問題的根本原因,其實還是因為編譯器給開發人員蒙上了一層迷霧,導致一些開發人員只知其然,而不知其所以然,他們根本不清楚自己寫出來的程式,實際上到底是如何啟動並執行。這樣的一層迷霧註定會降低開發人員的水平,所以為了提高自己,我們有必要揭開這層迷霧。對於C/C++的開發人員來講,揭開這層迷霧其實就是瞭解組合語言的過程。

  組合語言對於C/C++程式猿來講,就像class檔案對於Java程式猿是一樣的,因為它們都是編譯器處理後的產物,我們可以從當中簡單的瞭解一下兩者的關聯。

  這個圖中應該看起來還算比較清晰,其實LZ說了這麼多,只是想說一件事,那就是瞭解組合語言的知識,對我們平時的開發有著不可忽視的好處,尤其是對於從事C/C++的開發人員來說,好處更是無窮無盡的。

  可能會有猿友覺得,LZ是一個靠Java吃飯的傢伙,瞭解組合語言是不是有點多此一舉了,畢竟Java語言離彙編還是有點太遠了吧。畢竟Java要先編譯成class檔案,然後交給虛擬機器的執行引擎,而虛擬機器的執行引擎則是由C/C++來實現的,C/C++又需要經過預先處理和GCC編譯器的編譯才能最終成為組合語言。這猛地一看,Java確實離組合語言太遠了。

  可是LZ想說的是,無論你處於什麼樣的一個崗位當中,只要你做的事是指揮電腦協助你完成一些事情,那麼你就必須瞭解電腦如何幫你完成這些事情,否則你就只會指揮,而不會懂得如何去做。不知道如何去做的後果就是,你不會知道如何才能做的更好,反映到現實當中,就是你不知道如何寫出更好的程式。這點其實不難理解,試想一下,你都不知道你的程式實際上是如何啟動並執行,你又怎麼可能知道怎麼寫是更好的呢。

 

初次體會彙編

 

  在編譯一段C語言程式的過程中,其實做了很多步驟,比如先行編譯處理、編譯處理、彙編處理以及連結處理。我們要瞭解的組合語言,就是在編譯處理後的產物。因此我們可以在GCC的編譯器當中加入一些參數來控制它只產生組合語言,而不進行彙編處理和連結處理。

  我們看下面這一段簡單的C語言代碼,假設為sum.c。

int simple(int *xp,int y){    int t = *xp+y;    *xp=t;    return t;}

  我們使用GCC編譯器加-S參數來編譯這段代碼,最終我們可以得到一個sum.s的檔案,我們使用cat來查看一下這個檔案。

    .file    "sum.c"    .text.globl simple    .type    simple, @functionsimple:    pushl    %ebp    movl    %esp, %ebp    subl    $16, %esp    movl    8(%ebp), %eax//這一步是從主存取變數xp    movl    (%eax), %eax//取*xp的值    addl    12(%ebp), %eax//計算*xp+y,並存到%eax寄存器    movl    %eax, -4(%ebp)//將*xp+y賦給變數t    movl    8(%ebp), %eax//再取xp    movl    -4(%ebp), %edx//取t    movl    %edx, (%eax)//執行t->*xp    movl    -4(%ebp), %eax//將t放入%eax準備返回    leave    ret    .size    simple, .-simple    .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"    .section    .note.GNU-stack,"",@progbits

  這裡我們主要看一下組合語言是如何描述我們的計算過程的,因此LZ只是簡單的加了幾個注釋,來大致描述下上面的程式的計算過程。其中需要說明的是,以%開頭的為寄存器,有小括弧的為主存。

  熟悉GCC的猿友們應該知道,我們可以控制編譯器的最佳化層級,因此我們使用另外一種方式來編譯一下sum.c,我們在-S的基礎上再加一個-O1的參數。之後使用cat開啟sum.s檔案。

    .file    "sum.c"    .text.globl simple    .type    simple, @functionsimple:    pushl    %ebp    movl    %esp, %ebp    movl    8(%ebp), %edx//取xp    movl    12(%ebp), %eax//取y    addl    (%edx), %eax//計算*xp+y並存到%eax寄存器,準備返回    movl    %eax, (%edx)//將*xp+y存入*xp    popl    %ebp    ret    .size    simple, .-simple    .ident    "GCC: (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3"    .section    .note.GNU-stack,"",@progbits

  可以很明顯的看出,彙編指令的數目急劇減少,這裡LZ也加入了簡單的注釋。從LZ簡單的注釋中可以看出,這裡的最佳化主要是去掉了變數t的存在,因此減少了指令數。

  如果哪位猿友實在看不明白這兩段組合語言的含義,可以暫且忽略,這裡LZ只是讓各位體驗一下組合語言的格式,以及親自接觸一下組合語言,我們的目的並不是搞清楚它的意義。相信經過3.X的系列講解,各位猿友再回來看這兩段彙編代碼時,應該會很輕鬆的看出其中的意義。

 

文章小結

 

  這一章拖的時間有點久,主要是因為LZ作為一個Java開發人員來講,對組合語言的學習有些許難度,畢竟LZ並不擅長C/C++。還有一個原因,則是由於LZ希望盡量的搞清楚來龍去脈,以免誤導某些猿友。

  當然了,就算如此,LZ也不敢保證現在對3.X的內容已經了如指掌,因此如果文中有任何與各位猿友的理解不一致的地方,希望各位猿友儘管提出。不僅可以避免誤導看博文的猿友,還可以協助LZ糾正錯誤的認識。

  好了,本文的主要目的就是將各位猿友拉近彙編的世界,因此就只是簡單的介紹了一下。接下來,我們將深入的討論寄存器、資料格式以及一些彙編指令。

深入理解電腦系統(3.1)---走進彙編的世界

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.