精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Go 結(jié)構體函數(shù)調(diào)用底層實現(xiàn)

開發(fā) 后端
我們來了解一下結(jié)構體變量聲明和相關函數(shù)調(diào)用在機器碼或匯編層面的體現(xiàn)。我們以下面代碼為案例進行分析。

[[432712]]

《Go 語言嵌入和多態(tài)機制對比》一文中我們了解了 Go 語言的類型系統(tǒng)。下面,我們就來了解一下 Go 語言是如何實現(xiàn)類型系統(tǒng)特性,我們將會深入到 Go 語言運行時和最終機器碼層面對 Go 語言的結(jié)構體、函數(shù)調(diào)用進行了解。

上文已經(jīng)提及,Go 語言結(jié)構體并非 Java 和 C++ 語言中 class 的概念,下面我們來了解一下結(jié)構體變量聲明和相關函數(shù)調(diào)用在機器碼或匯編層面的體現(xiàn)。我們以下面代碼為案例進行分析。

  1. func (u User) addAgeVal(a int32) int32 { 
  2.     n := u.Age + a 
  3.     return n 
  4.  
  5. func (u *User) addAgePtr(a int32) int32 { 
  6.     n := u.Age + a 
  7.     return n 
  8. func main() { 
  9.     u := User{ID: 1, Name"Tom", Age: 23} 
  10.     s1 := u.addAgeVal(1) 
  11.     s2 := u.addAgePtr(2) 
  12.     println(s1 == s2) 

將上述代碼使用如下命令編譯成機器碼,其中 GOOS 指定目標操作系統(tǒng),GOARCH 指定 CPU 架構,-S 表示打印機器碼,-N 是禁止編譯器優(yōu)化,-l 是禁止內(nèi)聯(lián),本機 Go 版本為 go1.16.4。

  1. GOOS=linux GOARCH=amd64 go tool compile -S -N -l main.go 

變量聲明和初始化

我們首先來看 main 函數(shù)中 u 變量的聲明和初始化過程。匯編代碼較大,下面只截取部分內(nèi)容展示,具體如下所示。

由上可見,結(jié)構體真的就是基礎類型變量的集合,并沒有額外其他信息的加載,對于類型為 User 的 u 變量的聲明并初始化語句,首先將對應的棧內(nèi)空間清零,然后依次處理三個初始化參數(shù)值,并加載到對應的棧空間位置,完成初始化過程。

其中 ID 和 Age 由于是基礎類型,所以較為簡單,而 Name 字段涉及到 string 類型,稍有區(qū)別,String類型的運行時表達,具體如下所示。

  1. type** StringHeader struct { 
  2.     Data uintptr 
  3.     Len int 

由此可見上述匯編中首先將 Tom 字面量地址加載到棧內(nèi)空間,Tom 字面量則存儲在內(nèi)存數(shù)據(jù)段中,給 Data 變量賦值,然后將字面量的長度 3 加載到對應位置,給 Len 變量賦值,具體如下圖所示。

SP 代表棧頂指針,而 "".u +64(SP) 代表相對于棧頂偏移 64 字節(jié)的位置,u 則是引用地址的別名,也正是變量 u 的名稱。如圖所示,在棧空間中,并不存在結(jié)構體 User,而是由基礎類型數(shù)值和指針等組成的一段空間,這段空間就代表著結(jié)構體 User。

從棧頂向棧底方向依次為占 8 字節(jié)的代表 User.ID 的常量值1,占據(jù) 16 字節(jié)的代表 User.Name 的字符串 Tom 值地址和占據(jù) 8 字節(jié)的代表 User.Age 的常量 23,其中字符串 Tom 又由 8 字節(jié)的 Data 指針和 8 字節(jié)的 Len 組成。

上述代碼中變量 u 未發(fā)生逃逸,所以分配在棧中,如果將變量聲明成指針類型并且符合逃逸規(guī)則,該結(jié)構體就會分配在堆上。

  1. func makeUser() *User { 
  2.     u := &User{ID: 1, Name"Tom", Age: 23} 
  3.    return u 

上述指針變量聲明和初始化過程的匯編如下所示。

可以看出匯編代碼會首先將 Cat 結(jié)構體的類型指針加載到棧頂,作為參數(shù);然后調(diào)用 newObject 函數(shù)來在堆上按照 Cat 結(jié)構體類型分配對應的空間,并返回空間的起始地址;最后使用該起始地址設置結(jié)構體的變量。

分配在堆上的結(jié)構體示意圖在上一個圖的右側(cè)顯示。我們可以看到,當結(jié)構體分配在棧上時,其內(nèi)部成員變量會依次排列,占據(jù)各自固定的空間;而結(jié)構體分配在堆上時,其在棧上只會存在一個指向堆地址的指針,該指針指向結(jié)構體在堆上的起始位置。

值接收器函數(shù)

下面我們來看一下結(jié)構體作為函數(shù)接收器如何進行函數(shù)調(diào)用,包括如何如何傳遞參數(shù)和返回值,如何進行值接收器和指針接收器轉(zhuǎn)換等。上述例子中涉及函數(shù)調(diào)用的片段如下所示:

Go 的調(diào)用規(guī)約要求函數(shù)參數(shù)和返回值都通過棧來傳遞,這部分空間由調(diào)用方在其棧幀(stack frame)上提供。

  • 函數(shù)接收器是隱式的第一個函數(shù)參數(shù),所以上述代碼片段的第一步就是講變量 u 拷貝到對應的棧空間上,這也正對應了值接收器的拷貝機制;
  • 然后第二步則是聲明 int32 類型的值為 1 的參數(shù) a 并分配到指定位置;
  • 接著是使用 CALL 指令調(diào)用 User 的 addAgeVal 函數(shù),CALL 指令會將函數(shù)的返回值地址推到棧頂,也就是會存儲棧的 +40(SP) 位置上;
  • 而最后會將其值加載到 +60(SP) 上,也就是將函數(shù)返回值賦值給變量 s1。

下面,我們來看一下被調(diào)用函數(shù) addAgeVal 函數(shù)的相關機器碼表達。

addAgeVal 函數(shù)大致分為四個步驟:

  • 使用 SUBQ 指令將 SP 減少 16,代表棧增長 16 字節(jié),因為棧幀是向低位增長,其中 8 個字節(jié)用于存儲當前的棧幀指針,并使用 LEAQ 計算出新的棧幀指針存到BP中;
  • 初始化函數(shù)返回值,因為是其類型是 int32,所以將其設置為對應的零值,棧空間地址是 +64(SP);
  • 從 +48(SP) 位置加載函數(shù)接收器 User 的變量 Age 到 AX 寄存器,然后將其和函數(shù)參數(shù) a 累加,其位置為 +56(SP)
  • 將二者的和賦值給變量 n,并且將二者的和保存到返回值所在棧空間,也就是 +64(SP);
  • 從 8(SP) 中取出舊棧幀指針,并且將棧幀縮小 16 字節(jié),并調(diào)用 RET 指令返回。

綜上,main 函數(shù)調(diào)用 User 的 addAgeVal 函數(shù)的過程如下圖所示。

 如上圖所示,我們看到在 main 函數(shù)執(zhí)行 call 指令前,為調(diào)用函數(shù) addAgeVal 的參數(shù)和返回值準備好了空間,然后將函數(shù)接收器 u 和對應的參數(shù) a 按照順序拷貝到該空間上,然后預留 +40(SP) 的位置給函數(shù)調(diào)用的返回值。

也正是因為值接收器和函數(shù)參數(shù)發(fā)生拷貝,所以函數(shù)內(nèi)對其修改不會影響原值。

調(diào)用 call 指令時,會將指令返回地址壓入棧首,然后再執(zhí)行 addAgeVal 函數(shù)的指令,將棧頂增長 16 字節(jié),從而導致函數(shù)接收器、參數(shù)和返回值的相對于SP的地址發(fā)生變化,增加了 16 字節(jié),所以大家會發(fā)現(xiàn) addAgeVal 函數(shù)中指令操作的相對地址發(fā)生了變化。

指針接收器函數(shù)

下面,我們來看調(diào)用指針接收器函數(shù) addAgePtr 相關的具體指令,體會它與值接收器函數(shù)的區(qū)別。

可以看到調(diào)用 addAgePtr 時不會對接收器 u 進行拷貝,而只是將 u 的起始棧地址加載到棧頂,這其實就相當于傳遞了指向 u 的指針。然后是設置參數(shù) a 的值,最后使用 CALL 指令調(diào)用 addAgePtr 函數(shù)。

而 addAgePtr 函數(shù)的指令和 addAgeVal 類似,唯一不同的是要使用指針來獲取接收器 u 的 Age 變量的值,具體如下所示。

從對應的棧空間取到接收器 u 的指針,也就是其起始地址,從起始地址偏移 24 字節(jié)就是接收器 u 的 Age 變量位置。整個流程如下圖所示。

如上圖所示,可以看到指針接收器的函數(shù)調(diào)用時,只需要將其地址作為默認參數(shù)進行傳遞,所以在函數(shù)內(nèi)的對接收器的修改,都是直接修改在原值上。

此外,調(diào)用 addAgePtr 的場景是在值變量上調(diào)用指針接收器函數(shù),我們看到編譯器將值的地址取出作為接收器參數(shù)進行傳遞,而如果是指針變量調(diào)用值接收器函數(shù)的話,則會先對指針進行取地址,然后再將指針指向的值數(shù)據(jù)進行拷貝。

 

綜上,我們了解了 Go 語言中結(jié)構器和結(jié)構體函數(shù)在機器層級方面的底層實現(xiàn),后續(xù)文章我們再繼續(xù)了解 Go 語言相關特性的底層實現(xiàn)。

 

責任編輯:武曉燕 來源: 程序員歷小冰
相關推薦

2020-12-02 09:10:22

Go結(jié)構數(shù)據(jù)類型

2024-10-16 09:57:52

空結(jié)構體map屬性

2023-07-29 15:03:29

2021-04-20 09:00:48

Go 語言結(jié)構體type

2025-08-29 01:45:00

Go語言函數(shù)

2020-11-26 06:40:24

Go語言基礎

2020-12-02 08:45:36

Go語言

2020-11-30 06:17:03

Go語言

2017-08-31 11:28:47

Slice底層實現(xiàn)

2020-11-23 08:54:14

Go語言結(jié)構體

2023-11-21 08:03:43

語言架構偏移量

2021-12-21 08:51:13

Go數(shù)據(jù)Model

2021-12-20 07:59:07

Go語言結(jié)構體

2009-08-13 14:24:44

C#結(jié)構體構造函數(shù)

2021-11-15 06:56:46

Go語言Tag

2025-05-16 10:05:00

WOLGoSocket

2025-06-12 02:21:00

2021-08-29 07:41:48

數(shù)據(jù)HashMap底層

2021-11-02 14:54:41

Go結(jié)構體標簽

2024-10-14 08:51:52

協(xié)程Go語言
點贊
收藏

51CTO技術棧公眾號

国产高清在线观看免费不卡| 精品国产美女| 精品欧美一区二区三区| 精品在线一区| 一区二区三区精| 888av在线视频| a级高清视频欧美日韩| 日韩中文视频免费在线观看| 亚洲欧美日本一区二区| av福利在线导航| 国产精品五月天| 日韩美女视频中文字幕| 在线观看黄网址| 欧美激情影院| 欧美一区二区三区爱爱| 欧美日韩一区二区在线免费观看| 高清免费电影在线观看| 日本视频一区二区| 欧美精品videosex牲欧美| 色哟哟精品观看| 日韩精品成人在线观看| 色呦呦国产精品| 成人免费在线网| 欧美高清视频| 国产日产欧美精品一区二区三区| 国产精品久久国产精品| 国产精品欧美激情在线| 久久理论电影| 亚洲精品99久久久久| 五月激情五月婷婷| 日本.亚洲电影| 精品国产乱码久久久久久虫虫漫画 | 黄色在线视频网址| 欧美人妖视频| 日韩一区二区三免费高清| 国产免费999| 在线毛片观看| 五月婷婷欧美视频| 99热这里只有精品免费| 日韩欧美小视频| 久久久精品免费免费| 精品国产一区二区三区麻豆小说 | www.日韩在线| 99se婷婷在线视频观看| 国产乱色精品成人免费视频| 免费成人美女在线观看| 国产精品99蜜臀久久不卡二区| 亚洲久久在线观看| 国产精品美女久久久浪潮软件| 欧美激情一区二区三区在线视频观看| 2025国产精品自拍| 中文字幕一区二区三三| 久久国产加勒比精品无码| 91大神福利视频| 久久中文视频| 精品国产区一区二区三区在线观看| 国产伦精品一区二区三区视频女| av一区二区在线观看| 国产性猛交xxxx免费看久久| 超薄肉色丝袜一二三| 日本在线电影一区二区三区| 深夜福利日韩在线看| 日本一二三区在线观看| 一区二区三区在线| 色综合久久久888| www.99re7.com| 在线欧美一区| 日本中文字幕久久看| 国产成人a v| 捆绑调教美女网站视频一区| 91精品中文在线| 亚洲精品久久久久久动漫器材一区| 中文字幕亚洲综合久久五月天色无吗''| 在线视频一区二区| 日韩三级久久久| 国产精品分类| 日本欧美国产在线| 一级做a爰片久久毛片16| 国产麻豆欧美日韩一区| 国产精品伊人日日| 国产视频网址在线| 亚洲色图都市小说| 精品成在人线av无码免费看| 中文字幕在线看片| 欧美日韩中文字幕一区| 91人妻一区二区三区| 色豆豆成人网| 91精品国产91热久久久做人人| 免费黄色在线播放| 夜夜躁狠狠躁日日躁2021日韩| 中文字幕亚洲一区| 欧美黄片一区二区三区| 免播放器亚洲| 91在线中文字幕| 日韩大胆视频| 亚洲欧美偷拍三级| 欧美 国产 综合| **国产精品| 亚洲美女av在线| 日本高清一二三区| 蜜桃av一区| yellow视频在线观看一区二区 | 中日韩在线观看视频| 国产精品一区二区久久不卡 | 香蕉国产精品| 91福利视频网| 亚洲视频在线观看免费视频| 成人免费视频一区二区| 亚洲电影一二三区| 欧美gv在线| 午夜精品久久久久影视| wwww.国产| 五月天亚洲色图| 欧美日本高清一区| 亚洲字幕av一区二区三区四区| 北岛玲一区二区三区四区| 亚洲欧洲精品一区二区| 精精国产xxxx视频在线野外| 7878成人国产在线观看| 日本乱子伦xxxx| 一本综合久久| av日韩中文字幕| 国产传媒在线播放| 欧美日本在线播放| 免费污网站在线观看| 亚洲网站视频| 91视频九色网站| 最新97超碰在线| 欧洲一区在线观看| 精品人妻一区二区三区香蕉 | 亚洲欧美综合另类在线卡通| 久久久久久久久久久久久国产精品| 亚洲一区二区三区四区电影| 久久亚洲精品一区二区| 在线观看xxxx| 国产精品国产三级国产普通话99 | 综合国产精品久久久| 欧美free嫩15| 亚洲网站在线播放| 在线观看污污网站| 日本aⅴ免费视频一区二区三区 | 日韩一区二区在线| 国产99久久精品一区二区 夜夜躁日日躁 | 国产精品偷拍| 欧美小视频在线| 久久久久成人精品无码中文字幕| 欧美黄色大片网站| 7777精品伊久久久大香线蕉语言 | 国产精品极品美女在线观看免费 | 在线观看av大片| 国产精品久久综合| 色一情一区二区| 91日韩在线| 亚洲aa中文字幕| 直接在线观看的三级网址| 91精品一区二区三区久久久久久| 日本一二三区在线观看| 国产精品一区二区视频| 激情五月六月婷婷| 中文字幕视频精品一区二区三区| 欧美精品一区二区免费| 亚洲卡一卡二卡三| 偷拍亚洲欧洲综合| 国产精品三级在线观看无码| 日本久久黄色| 成人av番号网| 丝袜在线视频| 亚洲精品99999| 国产一级片一区二区| 国产精品理论片| 中文字幕亚洲日本| 亚洲免费播放| 日韩精品在在线一区二区中文| 国产成人免费| 欧美第一黄网免费网站| 亚洲三级中文字幕| 在线观看免费亚洲| 久久中文免费视频| 人妖欧美一区二区| 最新av在线免费观看| 亚洲网址在线观看| 欧美一区二区.| 无码人妻一区二区三区线| 日本一区二区三区免费乱视频 | 丰满岳乱妇一区二区三区| 久操网在线观看| 欧美日韩一二三四| 91精品国产91久久久久青草| 天堂av在线| 久久亚洲影音av资源网| 无码国产伦一区二区三区视频 | 亚洲第一免费视频| 色综合一个色综合| 玖玖爱这里只有精品| 91老师片黄在线观看| 天天色综合社区| 国产欧美69| 丰满女人性猛交| 尤物tv在线精品| y111111国产精品久久婷婷| 日韩视频网站在线观看| 欧美激情亚洲精品| 最新国产在线观看| 亚洲欧美另类在线观看| 国产超碰人人模人人爽人人添| 91久久一区二区| 国产在线视频99| 亚洲欧美日韩人成在线播放| 亚洲精品国产熟女久久久| 国产69精品久久久久毛片 | 国产精品老女人| 一区二区三区日韩在线观看| 三级视频中文字幕| 亚洲人体大胆视频| 路边理发店露脸熟妇泻火| 欧美精品一区二区久久| 国产综合18久久久久久| 国产日韩一区二区三免费高清| 国产精品99免视看9| 日韩伦理福利| 久久久久九九九九| 制服丝袜中文字幕在线| 久久精品国产欧美激情| 成人好色电影| 亚洲偷欧美偷国内偷| 日本黄色不卡视频| 精品免费一区二区三区| 国产乱淫a∨片免费视频| 欧美日韩精品一区二区三区| 欧美激情亚洲综合| 一区二区久久久久久| 999精品视频在线观看播放| 国产清纯美女被跳蛋高潮一区二区久久w | 精品亚洲自拍| 国产精品一区二区欧美| 日韩免费成人| 99久久综合狠狠综合久久止| 免费一级欧美在线大片| 91免费视频网站| 97久久精品一区二区三区的观看方式| 国产精品久久久久久婷婷天堂| 亚洲成a人片| 国产91色在线| 青青热久免费精品视频在线18| 国产99在线|中文| 日韩欧美一区二区三区在线观看| 日韩美女中文字幕| 欧美aaa大片视频一二区| 国产精品成人aaaaa网站| 精品视频在线一区二区在线| 国产精品视频精品| 日韩毛片网站| 亚洲综合成人婷婷小说| 视频一区视频二区欧美| 国产精品加勒比| 台湾色综合娱乐中文网| 欧美一区二区三区成人久久片| 日本免费在线一区| 国产中文字幕亚洲| 国产精品欧美一区二区三区不卡 | 韩国三级电影久久久久久| 激情在线视频| 国产一区二区动漫| 尤物网在线观看| 久久国产精品久久久| 欧洲成人综合网| 91国偷自产一区二区三区的观看方式| 自拍网站在线观看| 国产精品免费看久久久香蕉| 日韩伦理一区二区| 成人av男人的天堂| 日韩av系列| 亚洲视频sss| 国产精品草草| 少妇性l交大片| 精品一区二区三区在线观看 | 又骚又黄的视频| 日韩精品一区二区三区视频播放| 亚洲av成人精品一区二区三区在线播放 | 2018日韩中文字幕| 亚洲伦理影院| 91免费看网站| 国产麻豆精品久久| 久久久天堂国产精品| 亚洲综合日本| 91福利免费观看| 91网址在线看| 中文字幕无码日韩专区免费| 亚洲成人免费看| 久久免费看少妇高潮v片特黄 | 久久嫩草精品久久久精品| 成人性视频免费看| 亚洲午夜在线视频| 中国a一片一级一片| 亚洲白拍色综合图区| 国产成人精品白浆久久69| 亚洲第一网站男人都懂| 97电影在线| 欧美一区二区三区四区在线| 国产乱码精品一区二区三区亚洲人| 精品久久久久久一区二区里番| 欧美国产美女| 激情综合网婷婷| 高清视频一区二区| 国产免费嫩草影院| 欧美日韩精品国产| 国产又黄又猛又爽| 亚洲精品久久久久中文字幕二区| 里番在线观看网站| 日产日韩在线亚洲欧美| 成午夜精品一区二区三区软件| 性欧美videosex高清少妇| 亚洲日韩视频| 香蕉视频1024| 亚洲人成亚洲人成在线观看图片 | 国产乱妇无码大片在线观看| 播金莲一级淫片aaaaaaa| 亚洲一区二区免费视频| 国产一区二区三区三州| 精品亚洲永久免费精品| 国产美女一区视频| 91久久偷偷做嫩草影院| 999久久久精品国产| 国产一二三区av| 国产丝袜欧美中文另类| 五月激情六月丁香| 欧美v国产在线一区二区三区| 人人干在线视频| 国产精品中文久久久久久久| 九九在线高清精品视频| 北条麻妃在线视频观看| 成人av在线一区二区| 国产一级av毛片| 精品久久久网站| 国产嫩草在线视频| 国产精品一区二区三区在线| 中文字幕一区二区三区在线视频 | 国产婷婷一区二区三区| 成人精品小蝌蚪| 久久综合亚洲色hezyo国产| 日韩午夜av一区| 在线中文字幕第一页| 91av一区二区三区| 久久久久久久久久久妇女| 中文字幕永久有效| 亚洲欧美在线视频观看| 夜夜爽8888| 蜜臀久久99精品久久久无需会员 | 蜜臀av一区二区在线观看| 国内精品卡一卡二卡三| 欧美伊人精品成人久久综合97 | 99久久精品国产色欲| 久久久国产影院| 136国产福利精品导航网址应用| 国产爆乳无码一区二区麻豆| 成人综合婷婷国产精品久久蜜臀| 久久精品视频8| 日韩国产一区三区| 韩日精品一区二区| 天天久久人人| 国产一区二区在线视频| 久久久久久免费观看| 亚洲第一福利网| 芒果视频成人app| 亚洲最新在线| 国产成人精品网址| 欧美一级视频免费观看| 日韩精品中文字幕在线| 97成人超碰| av久久久久久| 久久一区二区视频| 亚洲天堂网视频| 欧美日韩国产第一页| 亚洲人挤奶视频| 亚洲这里只有精品| 亚洲一区二区在线免费看| 天堂在线中文字幕| 久久精品中文字幕免费mv| 国产精品欧美一区二区三区不卡| 欧美精品久久久久久久久久久| 国产拍欧美日韩视频二区| 国产欧美一区二区三区视频在线观看| 久久久久久久久久久亚洲| 亚洲国产最新| 九九久久久久久| 欧美视频在线免费看| 在线视频1区2区| 国产精品有限公司| 日韩不卡免费视频| 久久久久久免费观看| 尤物九九久久国产精品的特点| 久久69av| 久久精品视频91| 亚洲自拍偷拍av| 中文字幕日本在线观看| 国产一区二区三区无遮挡| 久久精品国产免费看久久精品| 国产精品第56页| 久久国内精品一国内精品| 羞羞色国产精品网站|