前沿拓展:
用這個(gè)方便的捕鼠器比喻來理解編譯代碼。
源代碼必須要經(jīng)過編譯才能夠運(yùn)行程序,而對(duì)于開源軟件,每個(gè)人都可以獲取源代碼。無論你是自己編寫了代碼,想要編譯和運(yùn)行它,還是下載了某人的項(xiàng)目來嘗試它,了解如何通過 編譯器處理源代碼,以及編譯器如何處理這些代碼,這都很有用。
創(chuàng)建一個(gè)更好的捕鼠器
一般情況我們不會(huì)將一個(gè)捕鼠器比作電腦,但不管你信不信,它確實(shí)與你正在使用的設(shè)備(手機(jī)或電腦)的 CPU 有一些相似之處。經(jīng)典的捕鼠器(我說的不是 ??)有兩種狀態(tài):打開或者釋放。你可以認(rèn)為 打開是將捕鼠器設(shè)置好準(zhǔn)備捕獲老鼠,以及釋放是捕鼠器被老鼠觸發(fā)。某種意義上來說,捕鼠器就像是一臺(tái)有鼠標(biāo)的電腦。你可以想象一下這個(gè)代碼,用一種虛構(gòu)的語言來描述這個(gè)過程:
if mousetrap == 0 then
There’s a mouse!
else
There’s no mouse yet.
end
換句話說,你可以基于捕鼠器的狀態(tài)發(fā)現(xiàn)是否有老鼠(數(shù)據(jù))。當(dāng)然,捕鼠器不是萬無一失的,有可能有一只老鼠在捕鼠器旁邊,由于老鼠還沒有觸發(fā)捕鼠器,所以它的狀態(tài)還是 打開的。因此該程序可以進(jìn)行改進(jìn),這都是非常典型的。
開關(guān)
總的來說,捕鼠器就是一個(gè)開關(guān)。你會(huì)在家里使用開關(guān)打開燈??梢詮拈_關(guān)中獲得許多信息。比如,人們會(huì)從你家燈的狀態(tài)了解到你是否在家。
你可以根據(jù)鄰居家燈的狀態(tài)來改變行為。如果鄰居家所有的燈都熄滅了,那么請(qǐng)關(guān)掉你大聲的音樂,因?yàn)槿藗兛赡芤呀?jīng)上床睡覺了。
CPU 也使用這樣的邏輯,只不過乘以幾個(gè)數(shù)量級(jí),縮小到了微觀級(jí)別。當(dāng) CPU 在特定寄存器上接收到電信號(hào)時(shí),可以觸發(fā)其他一些寄存器,第二觸發(fā)另一個(gè),以此類推。如果這些寄存器有特定的意義,那么就可以通信。也許激活同一主板上某處的芯片,或者使 LED 亮起,或者改變屏幕上的像素顏色。
種瓜得瓜,種豆得豆。如果你真的想在多個(gè)位置而不是僅限于一處發(fā)現(xiàn)老鼠,但是你只有一個(gè)捕鼠器,那你應(yīng)該開發(fā)一個(gè)應(yīng)用才行。使用網(wǎng)絡(luò)攝像頭和一些基本的圖像識(shí)別軟件,你可以建立空廚房的模型,第二掃描變化。當(dāng)老鼠進(jìn)入廚房,在原先沒有老鼠的圖像上會(huì)有像素的變化。記錄下這些數(shù)據(jù),如果有無人機(jī)可以**老鼠并捕獲會(huì)更好,這樣就可以將老鼠趕出廚房了。這時(shí),你通過打開和關(guān)閉信號(hào)的魔法,創(chuàng)造了一個(gè)更好的捕鼠器。
編譯器
代碼編譯器將人們可閱讀的代碼轉(zhuǎn)換成 CPU 可以理解的機(jī)器語言。這是非常復(fù)雜的過程,因?yàn)?CPU 非常復(fù)雜(甚至比捕鼠器更加復(fù)雜),同時(shí)因?yàn)樵撨^程比嚴(yán)格“需要”的更加靈活。并不是所有的編譯器都很靈活。有一些編譯器只有一個(gè)目標(biāo),它們只會(huì)處理特定格式的代碼文件,處理過程也因此而簡單明了。
幸運(yùn)的是,現(xiàn)代的通用編譯器并不簡單。它們?cè)试S你編寫不同語言的代碼,也允許你用不同的方式鏈接庫文件,并且可以生成運(yùn)行在不同架構(gòu)上的文件。GNU 編譯器**(GCC)的gcc編譯器–help會(huì)輸出超過 50 行的選項(xiàng),LLVM 的clang編譯器的–help輸出超過 1000 行。GCC 指導(dǎo)手冊(cè)的字?jǐn)?shù)超過 10 萬。
當(dāng)你在編譯代碼時(shí)會(huì)有很多選項(xiàng)。
當(dāng)然,大多數(shù)人并不需要知道所有的選項(xiàng)。我從未讀過 GCC 的手冊(cè)頁,因?yàn)樗鼈兪轻槍?duì) Objective-C、Fortran 以及我從未聽說過的芯片架構(gòu)的。不過我重視它將代碼編譯為不同的架構(gòu) —— 64 位或者 32 位 —— 的能力,以及在其他行業(yè)已經(jīng)落后的計(jì)算機(jī)上運(yùn)行開源軟件的能力。
編譯生命周期
同樣重要的是,理解編譯代碼的不同階段。這是一個(gè)簡單的 C 語言程序的生命周期:
帶有宏定義的 C 源代碼 .c文件,用cpp預(yù)處理為.i文件。擴(kuò)展了宏定義的 C 源代碼 .i文件,會(huì)被gcc轉(zhuǎn)譯成.s文件。以匯編語言寫的文本文件 .s文件被匯編為目標(biāo).o文件。帶有 CPU 指令的二進(jìn)制目標(biāo)代碼,以及其他目標(biāo)文件和庫 *.o文件,以內(nèi)存區(qū)域無關(guān)的偏移量,使用ld鏈接以生成可執(zhí)行文件。最終的二進(jìn)制文件要么包含所有需要的目標(biāo),要么設(shè)置以動(dòng)態(tài)鏈接庫 *.so文件加載。
你可以試試這個(gè)簡單示例(可能需要對(duì)庫路徑做一些調(diào)整):
$ cat > hello.c
#include
int main(void)
{ printf(“hello worldn”);
return 0; }
EOF
$ cpp hello.c > hello.i
$ gcc -S hello.i
$ as -o hello.o hello.s
$ ld -static -o hello
-L/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/
/usr/lib64/crt1.o /usr/lib64/crti.o hello.o
/usr/lib64/crtn.o –start-group -lc -lgcc
-lgcc_eh –end-group
$ ./hello
hello world
可獲得的知識(shí)
計(jì)算機(jī)已經(jīng)變得非常強(qiáng)大,并且用戶友好。請(qǐng)不要走向這兩種可能的極端中的任何一種:計(jì)算機(jī)不像捕鼠器和電燈開關(guān)那么簡單,但它們也不是無法理解的。你可以了解編譯代碼、如何鏈接以及針對(duì)不同架構(gòu)進(jìn)行編譯。一旦你知道了,你就可以更好地調(diào)試代碼。你可以理解你下載的代碼,甚至可以修復(fù)其中的一兩個(gè)錯(cuò)誤。同時(shí)從理論上來講,你可以建造一個(gè)更好的捕鼠器,或者用捕鼠器造一個(gè) CPU。由你決定。
via: https://opensource.com/article/22/10/compiling-code
作者:Alan **ithee選題:lkxed譯者:Donkey-Hao校對(duì):wxy
本文由 LCTT原創(chuàng)編譯,Linux**榮譽(yù)推出
拓展知識(shí):
前沿拓展:
用這個(gè)方便的捕鼠器比喻來理解編譯代碼。
源代碼必須要經(jīng)過編譯才能夠運(yùn)行程序,而對(duì)于開源軟件,每個(gè)人都可以獲取源代碼。無論你是自己編寫了代碼,想要編譯和運(yùn)行它,還是下載了某人的項(xiàng)目來嘗試它,了解如何通過 編譯器處理源代碼,以及編譯器如何處理這些代碼,這都很有用。
創(chuàng)建一個(gè)更好的捕鼠器
一般情況我們不會(huì)將一個(gè)捕鼠器比作電腦,但不管你信不信,它確實(shí)與你正在使用的設(shè)備(手機(jī)或電腦)的 CPU 有一些相似之處。經(jīng)典的捕鼠器(我說的不是 ??)有兩種狀態(tài):打開或者釋放。你可以認(rèn)為 打開是將捕鼠器設(shè)置好準(zhǔn)備捕獲老鼠,以及釋放是捕鼠器被老鼠觸發(fā)。某種意義上來說,捕鼠器就像是一臺(tái)有鼠標(biāo)的電腦。你可以想象一下這個(gè)代碼,用一種虛構(gòu)的語言來描述這個(gè)過程:
if mousetrap == 0 then
There’s a mouse!
else
There’s no mouse yet.
end
換句話說,你可以基于捕鼠器的狀態(tài)發(fā)現(xiàn)是否有老鼠(數(shù)據(jù))。當(dāng)然,捕鼠器不是萬無一失的,有可能有一只老鼠在捕鼠器旁邊,由于老鼠還沒有觸發(fā)捕鼠器,所以它的狀態(tài)還是 打開的。因此該程序可以進(jìn)行改進(jìn),這都是非常典型的。
開關(guān)
總的來說,捕鼠器就是一個(gè)開關(guān)。你會(huì)在家里使用開關(guān)打開燈。可以從開關(guān)中獲得許多信息。比如,人們會(huì)從你家燈的狀態(tài)了解到你是否在家。
你可以根據(jù)鄰居家燈的狀態(tài)來改變行為。如果鄰居家所有的燈都熄滅了,那么請(qǐng)關(guān)掉你大聲的音樂,因?yàn)槿藗兛赡芤呀?jīng)上床睡覺了。
CPU 也使用這樣的邏輯,只不過乘以幾個(gè)數(shù)量級(jí),縮小到了微觀級(jí)別。當(dāng) CPU 在特定寄存器上接收到電信號(hào)時(shí),可以觸發(fā)其他一些寄存器,第二觸發(fā)另一個(gè),以此類推。如果這些寄存器有特定的意義,那么就可以通信。也許激活同一主板上某處的芯片,或者使 LED 亮起,或者改變屏幕上的像素顏色。
種瓜得瓜,種豆得豆。如果你真的想在多個(gè)位置而不是僅限于一處發(fā)現(xiàn)老鼠,但是你只有一個(gè)捕鼠器,那你應(yīng)該開發(fā)一個(gè)應(yīng)用才行。使用網(wǎng)絡(luò)攝像頭和一些基本的圖像識(shí)別軟件,你可以建立空廚房的模型,第二掃描變化。當(dāng)老鼠進(jìn)入廚房,在原先沒有老鼠的圖像上會(huì)有像素的變化。記錄下這些數(shù)據(jù),如果有無人機(jī)可以**老鼠并捕獲會(huì)更好,這樣就可以將老鼠趕出廚房了。這時(shí),你通過打開和關(guān)閉信號(hào)的魔法,創(chuàng)造了一個(gè)更好的捕鼠器。
編譯器
代碼編譯器將人們可閱讀的代碼轉(zhuǎn)換成 CPU 可以理解的機(jī)器語言。這是非常復(fù)雜的過程,因?yàn)?CPU 非常復(fù)雜(甚至比捕鼠器更加復(fù)雜),同時(shí)因?yàn)樵撨^程比嚴(yán)格“需要”的更加靈活。并不是所有的編譯器都很靈活。有一些編譯器只有一個(gè)目標(biāo),它們只會(huì)處理特定格式的代碼文件,處理過程也因此而簡單明了。
幸運(yùn)的是,現(xiàn)代的通用編譯器并不簡單。它們?cè)试S你編寫不同語言的代碼,也允許你用不同的方式鏈接庫文件,并且可以生成運(yùn)行在不同架構(gòu)上的文件。GNU 編譯器**(GCC)的gcc編譯器–help會(huì)輸出超過 50 行的選項(xiàng),LLVM 的clang編譯器的–help輸出超過 1000 行。GCC 指導(dǎo)手冊(cè)的字?jǐn)?shù)超過 10 萬。
當(dāng)你在編譯代碼時(shí)會(huì)有很多選項(xiàng)。
當(dāng)然,大多數(shù)人并不需要知道所有的選項(xiàng)。我從未讀過 GCC 的手冊(cè)頁,因?yàn)樗鼈兪轻槍?duì) Objective-C、Fortran 以及我從未聽說過的芯片架構(gòu)的。不過我重視它將代碼編譯為不同的架構(gòu) —— 64 位或者 32 位 —— 的能力,以及在其他行業(yè)已經(jīng)落后的計(jì)算機(jī)上運(yùn)行開源軟件的能力。
編譯生命周期
同樣重要的是,理解編譯代碼的不同階段。這是一個(gè)簡單的 C 語言程序的生命周期:
帶有宏定義的 C 源代碼 .c文件,用cpp預(yù)處理為.i文件。擴(kuò)展了宏定義的 C 源代碼 .i文件,會(huì)被gcc轉(zhuǎn)譯成.s文件。以匯編語言寫的文本文件 .s文件被匯編為目標(biāo).o文件。帶有 CPU 指令的二進(jìn)制目標(biāo)代碼,以及其他目標(biāo)文件和庫 *.o文件,以內(nèi)存區(qū)域無關(guān)的偏移量,使用ld鏈接以生成可執(zhí)行文件。最終的二進(jìn)制文件要么包含所有需要的目標(biāo),要么設(shè)置以動(dòng)態(tài)鏈接庫 *.so文件加載。
你可以試試這個(gè)簡單示例(可能需要對(duì)庫路徑做一些調(diào)整):
$ cat > hello.c
#include
int main(void)
{ printf(“hello worldn”);
return 0; }
EOF
$ cpp hello.c > hello.i
$ gcc -S hello.i
$ as -o hello.o hello.s
$ ld -static -o hello
-L/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/
/usr/lib64/crt1.o /usr/lib64/crti.o hello.o
/usr/lib64/crtn.o –start-group -lc -lgcc
-lgcc_eh –end-group
$ ./hello
hello world
可獲得的知識(shí)
計(jì)算機(jī)已經(jīng)變得非常強(qiáng)大,并且用戶友好。請(qǐng)不要走向這兩種可能的極端中的任何一種:計(jì)算機(jī)不像捕鼠器和電燈開關(guān)那么簡單,但它們也不是無法理解的。你可以了解編譯代碼、如何鏈接以及針對(duì)不同架構(gòu)進(jìn)行編譯。一旦你知道了,你就可以更好地調(diào)試代碼。你可以理解你下載的代碼,甚至可以修復(fù)其中的一兩個(gè)錯(cuò)誤。同時(shí)從理論上來講,你可以建造一個(gè)更好的捕鼠器,或者用捕鼠器造一個(gè) CPU。由你決定。
via: https://opensource.com/article/22/10/compiling-code
作者:Alan **ithee選題:lkxed譯者:Donkey-Hao校對(duì):wxy
本文由 LCTT原創(chuàng)編譯,Linux**榮譽(yù)推出
拓展知識(shí):
前沿拓展:
用這個(gè)方便的捕鼠器比喻來理解編譯代碼。
源代碼必須要經(jīng)過編譯才能夠運(yùn)行程序,而對(duì)于開源軟件,每個(gè)人都可以獲取源代碼。無論你是自己編寫了代碼,想要編譯和運(yùn)行它,還是下載了某人的項(xiàng)目來嘗試它,了解如何通過 編譯器處理源代碼,以及編譯器如何處理這些代碼,這都很有用。
創(chuàng)建一個(gè)更好的捕鼠器
一般情況我們不會(huì)將一個(gè)捕鼠器比作電腦,但不管你信不信,它確實(shí)與你正在使用的設(shè)備(手機(jī)或電腦)的 CPU 有一些相似之處。經(jīng)典的捕鼠器(我說的不是 ??)有兩種狀態(tài):打開或者釋放。你可以認(rèn)為 打開是將捕鼠器設(shè)置好準(zhǔn)備捕獲老鼠,以及釋放是捕鼠器被老鼠觸發(fā)。某種意義上來說,捕鼠器就像是一臺(tái)有鼠標(biāo)的電腦。你可以想象一下這個(gè)代碼,用一種虛構(gòu)的語言來描述這個(gè)過程:
if mousetrap == 0 then
There’s a mouse!
else
There’s no mouse yet.
end
換句話說,你可以基于捕鼠器的狀態(tài)發(fā)現(xiàn)是否有老鼠(數(shù)據(jù))。當(dāng)然,捕鼠器不是萬無一失的,有可能有一只老鼠在捕鼠器旁邊,由于老鼠還沒有觸發(fā)捕鼠器,所以它的狀態(tài)還是 打開的。因此該程序可以進(jìn)行改進(jìn),這都是非常典型的。
開關(guān)
總的來說,捕鼠器就是一個(gè)開關(guān)。你會(huì)在家里使用開關(guān)打開燈。可以從開關(guān)中獲得許多信息。比如,人們會(huì)從你家燈的狀態(tài)了解到你是否在家。
你可以根據(jù)鄰居家燈的狀態(tài)來改變行為。如果鄰居家所有的燈都熄滅了,那么請(qǐng)關(guān)掉你大聲的音樂,因?yàn)槿藗兛赡芤呀?jīng)上床睡覺了。
CPU 也使用這樣的邏輯,只不過乘以幾個(gè)數(shù)量級(jí),縮小到了微觀級(jí)別。當(dāng) CPU 在特定寄存器上接收到電信號(hào)時(shí),可以觸發(fā)其他一些寄存器,第二觸發(fā)另一個(gè),以此類推。如果這些寄存器有特定的意義,那么就可以通信。也許激活同一主板上某處的芯片,或者使 LED 亮起,或者改變屏幕上的像素顏色。
種瓜得瓜,種豆得豆。如果你真的想在多個(gè)位置而不是僅限于一處發(fā)現(xiàn)老鼠,但是你只有一個(gè)捕鼠器,那你應(yīng)該開發(fā)一個(gè)應(yīng)用才行。使用網(wǎng)絡(luò)攝像頭和一些基本的圖像識(shí)別軟件,你可以建立空廚房的模型,第二掃描變化。當(dāng)老鼠進(jìn)入廚房,在原先沒有老鼠的圖像上會(huì)有像素的變化。記錄下這些數(shù)據(jù),如果有無人機(jī)可以**老鼠并捕獲會(huì)更好,這樣就可以將老鼠趕出廚房了。這時(shí),你通過打開和關(guān)閉信號(hào)的魔法,創(chuàng)造了一個(gè)更好的捕鼠器。
編譯器
代碼編譯器將人們可閱讀的代碼轉(zhuǎn)換成 CPU 可以理解的機(jī)器語言。這是非常復(fù)雜的過程,因?yàn)?CPU 非常復(fù)雜(甚至比捕鼠器更加復(fù)雜),同時(shí)因?yàn)樵撨^程比嚴(yán)格“需要”的更加靈活。并不是所有的編譯器都很靈活。有一些編譯器只有一個(gè)目標(biāo),它們只會(huì)處理特定格式的代碼文件,處理過程也因此而簡單明了。
幸運(yùn)的是,現(xiàn)代的通用編譯器并不簡單。它們?cè)试S你編寫不同語言的代碼,也允許你用不同的方式鏈接庫文件,并且可以生成運(yùn)行在不同架構(gòu)上的文件。GNU 編譯器**(GCC)的gcc編譯器–help會(huì)輸出超過 50 行的選項(xiàng),LLVM 的clang編譯器的–help輸出超過 1000 行。GCC 指導(dǎo)手冊(cè)的字?jǐn)?shù)超過 10 萬。
當(dāng)你在編譯代碼時(shí)會(huì)有很多選項(xiàng)。
當(dāng)然,大多數(shù)人并不需要知道所有的選項(xiàng)。我從未讀過 GCC 的手冊(cè)頁,因?yàn)樗鼈兪轻槍?duì) Objective-C、Fortran 以及我從未聽說過的芯片架構(gòu)的。不過我重視它將代碼編譯為不同的架構(gòu) —— 64 位或者 32 位 —— 的能力,以及在其他行業(yè)已經(jīng)落后的計(jì)算機(jī)上運(yùn)行開源軟件的能力。
編譯生命周期
同樣重要的是,理解編譯代碼的不同階段。這是一個(gè)簡單的 C 語言程序的生命周期:
帶有宏定義的 C 源代碼 .c文件,用cpp預(yù)處理為.i文件。擴(kuò)展了宏定義的 C 源代碼 .i文件,會(huì)被gcc轉(zhuǎn)譯成.s文件。以匯編語言寫的文本文件 .s文件被匯編為目標(biāo).o文件。帶有 CPU 指令的二進(jìn)制目標(biāo)代碼,以及其他目標(biāo)文件和庫 *.o文件,以內(nèi)存區(qū)域無關(guān)的偏移量,使用ld鏈接以生成可執(zhí)行文件。最終的二進(jìn)制文件要么包含所有需要的目標(biāo),要么設(shè)置以動(dòng)態(tài)鏈接庫 *.so文件加載。
你可以試試這個(gè)簡單示例(可能需要對(duì)庫路徑做一些調(diào)整):
$ cat > hello.c
#include
int main(void)
{ printf(“hello worldn”);
return 0; }
EOF
$ cpp hello.c > hello.i
$ gcc -S hello.i
$ as -o hello.o hello.s
$ ld -static -o hello
-L/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/
/usr/lib64/crt1.o /usr/lib64/crti.o hello.o
/usr/lib64/crtn.o –start-group -lc -lgcc
-lgcc_eh –end-group
$ ./hello
hello world
可獲得的知識(shí)
計(jì)算機(jī)已經(jīng)變得非常強(qiáng)大,并且用戶友好。請(qǐng)不要走向這兩種可能的極端中的任何一種:計(jì)算機(jī)不像捕鼠器和電燈開關(guān)那么簡單,但它們也不是無法理解的。你可以了解編譯代碼、如何鏈接以及針對(duì)不同架構(gòu)進(jìn)行編譯。一旦你知道了,你就可以更好地調(diào)試代碼。你可以理解你下載的代碼,甚至可以修復(fù)其中的一兩個(gè)錯(cuò)誤。同時(shí)從理論上來講,你可以建造一個(gè)更好的捕鼠器,或者用捕鼠器造一個(gè) CPU。由你決定。
via: https://opensource.com/article/22/10/compiling-code
作者:Alan **ithee選題:lkxed譯者:Donkey-Hao校對(duì):wxy
本文由 LCTT原創(chuàng)編譯,Linux**榮譽(yù)推出
拓展知識(shí):
前沿拓展:
用這個(gè)方便的捕鼠器比喻來理解編譯代碼。
源代碼必須要經(jīng)過編譯才能夠運(yùn)行程序,而對(duì)于開源軟件,每個(gè)人都可以獲取源代碼。無論你是自己編寫了代碼,想要編譯和運(yùn)行它,還是下載了某人的項(xiàng)目來嘗試它,了解如何通過 編譯器處理源代碼,以及編譯器如何處理這些代碼,這都很有用。
創(chuàng)建一個(gè)更好的捕鼠器
一般情況我們不會(huì)將一個(gè)捕鼠器比作電腦,但不管你信不信,它確實(shí)與你正在使用的設(shè)備(手機(jī)或電腦)的 CPU 有一些相似之處。經(jīng)典的捕鼠器(我說的不是 ??)有兩種狀態(tài):打開或者釋放。你可以認(rèn)為 打開是將捕鼠器設(shè)置好準(zhǔn)備捕獲老鼠,以及釋放是捕鼠器被老鼠觸發(fā)。某種意義上來說,捕鼠器就像是一臺(tái)有鼠標(biāo)的電腦。你可以想象一下這個(gè)代碼,用一種虛構(gòu)的語言來描述這個(gè)過程:
if mousetrap == 0 then
There’s a mouse!
else
There’s no mouse yet.
end
換句話說,你可以基于捕鼠器的狀態(tài)發(fā)現(xiàn)是否有老鼠(數(shù)據(jù))。當(dāng)然,捕鼠器不是萬無一失的,有可能有一只老鼠在捕鼠器旁邊,由于老鼠還沒有觸發(fā)捕鼠器,所以它的狀態(tài)還是 打開的。因此該程序可以進(jìn)行改進(jìn),這都是非常典型的。
開關(guān)
總的來說,捕鼠器就是一個(gè)開關(guān)。你會(huì)在家里使用開關(guān)打開燈??梢詮拈_關(guān)中獲得許多信息。比如,人們會(huì)從你家燈的狀態(tài)了解到你是否在家。
你可以根據(jù)鄰居家燈的狀態(tài)來改變行為。如果鄰居家所有的燈都熄滅了,那么請(qǐng)關(guān)掉你大聲的音樂,因?yàn)槿藗兛赡芤呀?jīng)上床睡覺了。
CPU 也使用這樣的邏輯,只不過乘以幾個(gè)數(shù)量級(jí),縮小到了微觀級(jí)別。當(dāng) CPU 在特定寄存器上接收到電信號(hào)時(shí),可以觸發(fā)其他一些寄存器,第二觸發(fā)另一個(gè),以此類推。如果這些寄存器有特定的意義,那么就可以通信。也許激活同一主板上某處的芯片,或者使 LED 亮起,或者改變屏幕上的像素顏色。
種瓜得瓜,種豆得豆。如果你真的想在多個(gè)位置而不是僅限于一處發(fā)現(xiàn)老鼠,但是你只有一個(gè)捕鼠器,那你應(yīng)該開發(fā)一個(gè)應(yīng)用才行。使用網(wǎng)絡(luò)攝像頭和一些基本的圖像識(shí)別軟件,你可以建立空廚房的模型,第二掃描變化。當(dāng)老鼠進(jìn)入廚房,在原先沒有老鼠的圖像上會(huì)有像素的變化。記錄下這些數(shù)據(jù),如果有無人機(jī)可以**老鼠并捕獲會(huì)更好,這樣就可以將老鼠趕出廚房了。這時(shí),你通過打開和關(guān)閉信號(hào)的魔法,創(chuàng)造了一個(gè)更好的捕鼠器。
編譯器
代碼編譯器將人們可閱讀的代碼轉(zhuǎn)換成 CPU 可以理解的機(jī)器語言。這是非常復(fù)雜的過程,因?yàn)?CPU 非常復(fù)雜(甚至比捕鼠器更加復(fù)雜),同時(shí)因?yàn)樵撨^程比嚴(yán)格“需要”的更加靈活。并不是所有的編譯器都很靈活。有一些編譯器只有一個(gè)目標(biāo),它們只會(huì)處理特定格式的代碼文件,處理過程也因此而簡單明了。
幸運(yùn)的是,現(xiàn)代的通用編譯器并不簡單。它們?cè)试S你編寫不同語言的代碼,也允許你用不同的方式鏈接庫文件,并且可以生成運(yùn)行在不同架構(gòu)上的文件。GNU 編譯器**(GCC)的gcc編譯器–help會(huì)輸出超過 50 行的選項(xiàng),LLVM 的clang編譯器的–help輸出超過 1000 行。GCC 指導(dǎo)手冊(cè)的字?jǐn)?shù)超過 10 萬。
當(dāng)你在編譯代碼時(shí)會(huì)有很多選項(xiàng)。
當(dāng)然,大多數(shù)人并不需要知道所有的選項(xiàng)。我從未讀過 GCC 的手冊(cè)頁,因?yàn)樗鼈兪轻槍?duì) Objective-C、Fortran 以及我從未聽說過的芯片架構(gòu)的。不過我重視它將代碼編譯為不同的架構(gòu) —— 64 位或者 32 位 —— 的能力,以及在其他行業(yè)已經(jīng)落后的計(jì)算機(jī)上運(yùn)行開源軟件的能力。
編譯生命周期
同樣重要的是,理解編譯代碼的不同階段。這是一個(gè)簡單的 C 語言程序的生命周期:
帶有宏定義的 C 源代碼 .c文件,用cpp預(yù)處理為.i文件。擴(kuò)展了宏定義的 C 源代碼 .i文件,會(huì)被gcc轉(zhuǎn)譯成.s文件。以匯編語言寫的文本文件 .s文件被匯編為目標(biāo).o文件。帶有 CPU 指令的二進(jìn)制目標(biāo)代碼,以及其他目標(biāo)文件和庫 *.o文件,以內(nèi)存區(qū)域無關(guān)的偏移量,使用ld鏈接以生成可執(zhí)行文件。最終的二進(jìn)制文件要么包含所有需要的目標(biāo),要么設(shè)置以動(dòng)態(tài)鏈接庫 *.so文件加載。
你可以試試這個(gè)簡單示例(可能需要對(duì)庫路徑做一些調(diào)整):
$ cat > hello.c
#include
int main(void)
{ printf(“hello worldn”);
return 0; }
EOF
$ cpp hello.c > hello.i
$ gcc -S hello.i
$ as -o hello.o hello.s
$ ld -static -o hello
-L/usr/lib64/gcc/x86_64-slackware-linux/5.5.0/
/usr/lib64/crt1.o /usr/lib64/crti.o hello.o
/usr/lib64/crtn.o –start-group -lc -lgcc
-lgcc_eh –end-group
$ ./hello
hello world
可獲得的知識(shí)
計(jì)算機(jī)已經(jīng)變得非常強(qiáng)大,并且用戶友好。請(qǐng)不要走向這兩種可能的極端中的任何一種:計(jì)算機(jī)不像捕鼠器和電燈開關(guān)那么簡單,但它們也不是無法理解的。你可以了解編譯代碼、如何鏈接以及針對(duì)不同架構(gòu)進(jìn)行編譯。一旦你知道了,你就可以更好地調(diào)試代碼。你可以理解你下載的代碼,甚至可以修復(fù)其中的一兩個(gè)錯(cuò)誤。同時(shí)從理論上來講,你可以建造一個(gè)更好的捕鼠器,或者用捕鼠器造一個(gè) CPU。由你決定。
via: https://opensource.com/article/22/10/compiling-code
作者:Alan **ithee選題:lkxed譯者:Donkey-Hao校對(duì):wxy
本文由 LCTT原創(chuàng)編譯,Linux**榮譽(yù)推出
拓展知識(shí):
原創(chuàng)文章,作者:九賢生活小編,如若轉(zhuǎn)載,請(qǐng)注明出處:http:///103116.html