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