Golang二進(jìn)制反匯編問(wèn)題
Golang二進(jìn)制反匯編
Go的源碼是Plan 9匯編與Go語(yǔ)言的混合使用,即有匯編調(diào)用Go,也有Go調(diào)用匯編。
在很多情況下,直接看匯編代碼更直觀,特別是在研究編譯器生成的函數(shù)實(shí)現(xiàn)時(shí)更有用。
下面介紹兩種反匯編方法:
假設(shè)有個(gè)helloworld.go程序,源碼如下:
package main import "fmt" func main() { fmt.Println("Hello, World!") }
先將代碼編譯成二進(jìn)制,命令如下:
go build --gcflags="-l -N" -o helloworld
會(huì)生成一個(gè)helloworld的二進(jìn)制,--gcflags="-l -N"
參數(shù)的作用是去掉編譯器優(yōu)化,使生成的匯編代碼與編寫的代碼更相近,同時(shí)也方便GDB調(diào)試。
反匯編成AT&T匯編
AT&T是Linux操作系統(tǒng)最常用的匯編語(yǔ)言,Linux系統(tǒng)提供的objdump工具也是將二進(jìn)制反編譯成AT&T匯編,命令如下:
objdump -d helloworld > att.asm
最終反匯編的結(jié)果放在了att.asm文件。
下面是匯編結(jié)果(截取了部分代碼):
0000000000487200 <main.main>: 487200: 64 48 8b 0c 25 f8 ff mov %fs:0xfffffffffffffff8,%rcx 487207: ff ff 487209: 48 3b 61 10 cmp 0x10(%rcx),%rsp 48720d: 76 7a jbe 487289 <main.main+0x89> 48720f: 48 83 ec 68 sub $0x68,%rsp 487213: 48 89 6c 24 60 mov %rbp,0x60(%rsp) 487218: 48 8d 6c 24 60 lea 0x60(%rsp),%rbp 48721d: 0f 57 c0 xorps %xmm0,%xmm0 487220: 0f 11 44 24 38 movups %xmm0,0x38(%rsp) 487225: 48 8d 44 24 38 lea 0x38(%rsp),%rax ...
反匯編成Plan 9匯編
Plan 9目前看到的只有Go語(yǔ)言在用,而且網(wǎng)上的資料很匱乏,學(xué)習(xí)成本挺高的,但如果學(xué)會(huì)了Plan 9匯編,再看Go源碼會(huì)非常簡(jiǎn)單,而且可以通過(guò)Go調(diào)用匯編寫出高效率代碼。
要把二進(jìn)制反匯編成Plan 9匯編,也只能用Go提供的工具,命令如下:
go tool objdump -S helloworld > plan9.asm
最終反匯編的結(jié)果放在了plan9.asm文件。
下面是匯編結(jié)果(截取了部分代碼):
TEXT main.main(SB) /root/program/golang/helloworld/helloworld.go func main() { 0x487200 64488b0c25f8ffffff MOVQ FS:0xfffffff8, CX 0x487209 483b6110 CMPQ 0x10(CX), SP 0x48720d 767a JBE 0x487289 0x48720f 4883ec68 SUBQ $0x68, SP 0x487213 48896c2460 MOVQ BP, 0x60(SP) 0x487218 488d6c2460 LEAQ 0x60(SP), BP fmt.Println("Hello, World!") 0x48721d 0f57c0 XORPS X0, X0 0x487220 0f11442438 MOVUPS X0, 0x38(SP) 0x487225 488d442438 LEAQ 0x38(SP), AX 0x48722a 4889442430 MOVQ AX, 0x30(SP)
建議
從上面展示的結(jié)果來(lái)看,兩種匯編還是有點(diǎn)差別的。
在學(xué)習(xí)Go源碼時(shí),選擇用哪種匯編去看這個(gè)要根據(jù)自已的實(shí)際情況來(lái)。
我的建議先必須對(duì)AT&T匯編有一定了解,因?yàn)镻lan 9匯編資料實(shí)在是太少了,甚至沒(méi)有一個(gè)對(duì)命令的完整介紹,一個(gè)沒(méi)有匯編基礎(chǔ)的人直接看Plan 9的一些文檔,絕對(duì)會(huì)一臉絕望。
在整理網(wǎng)上一些Plan 9匯編資料時(shí),發(fā)現(xiàn)都是講的Plan 9與AT&T的差異,所以只有了解AT&T,才能進(jìn)一步學(xué)好Plan 9匯編。
總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
go?build失敗報(bào)方法undefined的解決過(guò)程
go build命令用于編譯我們指定的源碼文件或代碼包以及它們的依賴包,下面這篇文章主要給大家介紹了關(guān)于go?build失敗報(bào)方法undefined的解決過(guò)程,文中通過(guò)實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下2022-11-11go語(yǔ)言環(huán)境變量設(shè)置全過(guò)程
這篇文章主要介紹了go語(yǔ)言環(huán)境變量設(shè)置全過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-05-05Golang實(shí)現(xiàn)yaml配置文件的解析
這篇文章主要介紹了Golang實(shí)現(xiàn)yaml配置文件的解析,文中通過(guò)圖文結(jié)合的方式講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-12-12Golang 利用反射對(duì)結(jié)構(gòu)體優(yōu)雅排序的操作方法
這篇文章主要介紹了Golang 利用反射對(duì)結(jié)構(gòu)體優(yōu)雅排序的操作方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-10-10Go?gRPC進(jìn)階教程gRPC轉(zhuǎn)換HTTP
這篇文章主要為大家介紹了Go?gRPC進(jìn)階教程gRPC轉(zhuǎn)換HTTP教程示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06使用Golang如何實(shí)現(xiàn)簡(jiǎn)易的令牌桶算法
這篇文章主要介紹了使用Golang如何實(shí)現(xiàn)簡(jiǎn)易的令牌桶算法問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07