最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Go 中的循環(huán)是如何轉(zhuǎn)為匯編的(方法詳解)

 更新時(shí)間:2020年05月06日 09:17:56   作者:Go語(yǔ)言中文網(wǎng)  
這篇文章主要介紹了Go 中的循環(huán)是如何轉(zhuǎn)為匯編的,本文通過(guò)循環(huán)的匯編代碼給大家講解的非常詳細(xì),代碼簡(jiǎn)單易懂,非常不錯(cuò),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下

本文基于 Go 1.13 版本

循環(huán)在編程中是一個(gè)重要的概念,且易于上手。但是,循環(huán)必須被翻譯成計(jì)算機(jī)能理解的底層指令。它的編譯方式也會(huì)在一定程度上影響到標(biāo)準(zhǔn)庫(kù)中的其他組件。讓我們開(kāi)始分析循環(huán)吧。

循環(huán)的匯編代碼

使用循壞迭代 array , slicechannel ,以下是一個(gè)使用循環(huán)對(duì) slice 計(jì)算總和的例子。

func main() {
 l := []int{9, 45, 23, 67, 78}
 t := 0

 for _, v := range l {
 t += v
 }

 println(t)
}

使用 go tool compile -S main.go 生成的匯編代碼,以下為相關(guān)輸出:

0x0041 00065 (main.go:4)   XORL   AX, AX
0x0043 00067 (main.go:4)   XORL   CX, CX

0x0045 00069 (main.go:7)   JMP    82
0x0047 00071 (main.go:7)   MOVQ   ""..autotmp_5+16(SP)(AX*8), DX
0x004c 00076 (main.go:7)   INCQ   AX
0x004f 00079 (main.go:8)   ADDQ   DX, CX
0x0052 00082 (main.go:7)   CMPQ   AX, $5
0x0056 00086 (main.go:7)   JLT    71
0x0058 00088 (main.go:11)  MOVQ   CX, "".t+8(SP)

我把這些指令分為了兩個(gè)部分,初始化部分和循環(huán)主體。前兩條指令,將兩個(gè)寄存器初始化為零值。

0x0041 00065 (main.go:4)   XORL   AX, AX
0x0043 00067 (main.go:4)   XORL   CX, CX

寄存器 AX 包含著當(dāng)前循環(huán)所處位置,而 CX 包含著變量 t 的值,下面為帶有指令和通用寄存器的直觀表示:

循環(huán)從表示「跳轉(zhuǎn)到指令 82 」的 JMP 82 開(kāi)始,這條指令的作用可以通過(guò)第二行來(lái)判斷:

接下來(lái)的指令 CMPQ AX,$5 表示「比較寄存器 AX5 」,事實(shí)上,這個(gè)操作是把 AX 中的值減去 5 ,然后儲(chǔ)存在另一個(gè)寄存器中,這個(gè)值可以被用在下一條指令 JLT 71 中,它的含義是 「如果值小于 0 則跳轉(zhuǎn)到指令 71 」,以下是更新后的直觀表示:

如果不滿足條件,則程序?qū)?huì)跳轉(zhuǎn)到循環(huán)體之后的下一條指令執(zhí)行。

所以,我們現(xiàn)在有了對(duì)循環(huán)的基本框架,以下是轉(zhuǎn)換后的 Go 循環(huán):

goto end
start:
 ?
end:
 if i < 5 {
 goto start
 }

println(t)

我們?nèi)鄙倭搜h(huán)的主體,接下來(lái),我們看看這部分的指令:

0x0047 00071 (main.go:7)   MOVQ   ""..autotmp_5+16(SP)(AX*8), DX
0x004c 00076 (main.go:7)   INCQ   AX
0x004f 00079 (main.go:8)   ADDQ   DX, CX

第一條指令 MOVQ ""..autotmp_5+16(SP)(AX*8), DX 表示 「將內(nèi)存從源位置移動(dòng)到目標(biāo)地址」,它由以下幾個(gè)部分組成:

""..autotmp_5+16(SP) 表示 slice ,而 SP 表示了棧指針即我們當(dāng)前的內(nèi)存空間, autotmp_* 是自動(dòng)生成變量名。

  • 偏差為 8 是因?yàn)樵?64 位計(jì)算機(jī)架構(gòu)中, int 類型是 8 字節(jié)的。
  • 偏差乘以寄存器 AX 的值,表示當(dāng)前循環(huán)中的位置。
  • 寄存器 DX 代表的目標(biāo)地址內(nèi)包含著循環(huán)的當(dāng)前值。

之后, INCQ 表示自增,然后會(huì)增加循環(huán)的當(dāng)前位置:

 

循環(huán)主體的最后一條指令是 ADDQ DX, CX ,表示把 DX 的值加在 CX ,所以我們可以看出, DX 所包含的值是目前循環(huán)所代表的的值,而 CX 代表了變量 t 的值。

他會(huì)一直循環(huán)至計(jì)數(shù)器到 5 ,之后循環(huán)體之后的指令表示為將寄存器 CX 的值賦予 t

0x0058 00088 (main.go:11)   MOVQ   CX, "".t+8(SP)

以下為最終狀態(tài)的示意圖:

我們可以完善 Go 中循環(huán)的轉(zhuǎn)換:

func main() {
 l := []int{9, 45, 23, 67, 78}
 t := 0
 i := 0

 var tmp int

 goto end
start:
 tmp = l[i]
 i++
 t += tmp
end:
 if i < 5 {
 goto start
 }

 println(t)
}

這個(gè)程序生成的匯編代碼與上文所提到的函數(shù)生成的匯編代碼有著相同的輸出。

改進(jìn)

循環(huán)的內(nèi)部轉(zhuǎn)換方式可能會(huì)對(duì)其他特性(如 Go 調(diào)度器)產(chǎn)生影響。在 Go 1.10 之前,循環(huán)像下面的代碼一樣編譯:

func main() {
 l := []int{9, 45, 23, 67, 78}
 t := 0
 i := 0

 var tmp int
 p := uintptr(unsafe.Pointer(&l[0]))

 if i >= 5 {
 goto end
 }
body:
 tmp = *(*int)(unsafe.Pointer(p))
 p += unsafe.Sizeof(l[0])
 i++
 t += tmp
 if i < 5 {
 goto body
 }
end:
 println(t)
}

這種實(shí)現(xiàn)方式的問(wèn)題是,當(dāng) i 達(dá)到 5 時(shí),指針 p 已經(jīng)超過(guò)了內(nèi)存分配空間的尾部。這個(gè)問(wèn)題使得循環(huán)不容易搶占,因?yàn)樗闹黧w是不安全的。循環(huán)編譯的優(yōu)化確保它不會(huì)創(chuàng)建任何越界的指針。這個(gè)改進(jìn)是為 Go 調(diào)度器中的非合作搶占做準(zhǔn)備的。你可以在這篇Proposal 中到更詳細(xì)的討論。

到此這篇關(guān)于Go 中的循環(huán)是如何轉(zhuǎn)為匯編的(方法詳解)的文章就介紹到這了,更多相關(guān)go 循環(huán)匯編內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 詳解匯編語(yǔ)言 dup偽指令

    詳解匯編語(yǔ)言 dup偽指令

    dup它有多種意義,包括Linux c 函數(shù)、C語(yǔ)言函數(shù)DUP、匯編指令、化學(xué)物質(zhì)DUP。這篇文章主要介紹了匯編語(yǔ)言 dup偽指令的相關(guān)知識(shí),需要的朋友可以參考下
    2020-01-01
  • 匯編語(yǔ)言實(shí)現(xiàn)在指定字符串中搜索字符''A''的方法

    匯編語(yǔ)言實(shí)現(xiàn)在指定字符串中搜索字符''A''的方法

    這篇文章主要介紹了匯編語(yǔ)言實(shí)現(xiàn)在指定字符串中搜索字符'A'的方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 匯編語(yǔ)言位向量(位映射)的實(shí)現(xiàn)

    匯編語(yǔ)言位向量(位映射)的實(shí)現(xiàn)

    這篇文章主要介紹了匯編語(yǔ)言位向量(位映射)的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • 匯編語(yǔ)言存儲(chǔ)及寄存器原理解析

    匯編語(yǔ)言存儲(chǔ)及寄存器原理解析

    這篇文章主要介紹了匯編語(yǔ)言存儲(chǔ)及寄存器原理解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-01-01
  • 匯編實(shí)現(xiàn)直接插入排序的方法示例

    匯編實(shí)現(xiàn)直接插入排序的方法示例

    這篇文章主要介紹了匯編實(shí)現(xiàn)直接插入排序的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 匯編語(yǔ)言中的各種寄存器介紹

    匯編語(yǔ)言中的各種寄存器介紹

    匯編語(yǔ)言(assembly language)是一種用于電子計(jì)算機(jī)、微處理器、微控制器或其他可編程器件的低級(jí)語(yǔ)言,亦稱為符號(hào)語(yǔ)言.這篇文章主要介紹了匯編語(yǔ)言中的各種寄存器介紹,需要的朋友可以參考下
    2020-01-01
  • 匯編語(yǔ)言指令集之條件轉(zhuǎn)移指令實(shí)現(xiàn)

    匯編語(yǔ)言指令集之條件轉(zhuǎn)移指令實(shí)現(xiàn)

    這篇文章主要介紹了匯編語(yǔ)言指令集之條件轉(zhuǎn)移指令實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-01-01
  • VScode配置8086匯編環(huán)境的過(guò)程解析

    VScode配置8086匯編環(huán)境的過(guò)程解析

    這篇文章主要介紹了VScode配置8086匯編環(huán)境的過(guò)程解析,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-04-04
  • 匯編實(shí)現(xiàn)冒泡排序的方法示例

    匯編實(shí)現(xiàn)冒泡排序的方法示例

    這篇文章主要介紹了匯編實(shí)現(xiàn)冒泡排序的方法示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-02-02
  • 匯編語(yǔ)言實(shí)現(xiàn)電子鬧鐘思路詳解

    匯編語(yǔ)言實(shí)現(xiàn)電子鬧鐘思路詳解

    這篇文章主要介紹了匯編語(yǔ)言實(shí)現(xiàn)電子鬧鐘思路詳解,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-02-02

最新評(píng)論

介休市| 唐河县| 襄汾县| 旬阳县| 本溪市| 固阳县| 浦东新区| 高要市| 灵武市| 隆化县| 南宫市| 中西区| 云安县| 多伦县| 桑日县| 凌云县| 清远市| 新巴尔虎右旗| 定安县| 普兰店市| 城市| 榆中县| 宣汉县| 建平县| 芒康县| 红安县| 九龙城区| 鄄城县| 云林县| 高密市| 松桃| 上蔡县| 甘孜| 桐庐县| 三原县| 龙游县| 富源县| 景德镇市| 阿勒泰市| 太和县| 安顺市|