汇编分析 Golang 循环(推荐)

 更新时间:2020年02月17日 16:13:06   转载 作者:360云计算  
循环是编程中很强大的一个概念,而且非常容易处理。这篇文章主要介绍了汇编分析 Golang 循环,需要的朋友可以参考下

女主宣言

今天小编为大家分享一篇关于Golang循环汇编分析的文章,文章中介绍了golang循环的汇编层面的处理,通过分析,我们可以更了解循环的实现。希望能对大家有所帮助。

PS:丰富的一线技术、多元化的表现形式,尽在“ 3 60云计算 ”,点关注哦!

循环是编程中很强大的一个概念,而且非常容易处理。 但是,必须将其翻译成机器可理解的基本指令。 它的编译方式也可能影响标准库中的其他组件。 让我们开始分析一下范围循环 。

1循环汇编

范围循环可以迭代数组,切片或通道。下面函数展示了,对分片进行循环并将数字相加:

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 可以转储生成汇编代码,下面为范围循环的相关代码。

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)

我们把指令分为两部分:初始化及循环本身。最开始两行指令用来初始化两个寄存器为0。

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

寄存器AX包含循环中的当前位置,而CX包含变量 t 的值。下面是带有指令和通用寄存器的直观表示:

该循环指令 JMP 82 开始,表示跳转到指令82。可以通过第二列来标识此目标指令:

下一条指令 CMPQ AX, $5 表示“比较寄存器AX和数值5”。它实际上是从AX中减去寄存器DX的值,并将结果存储到另一个寄存器中。现在,可以在下一条指令JLT 71中使用该值,该指令表示“如果小于0,则跳转到指令71。”下面是更新后的图:

如果条件不满足,则程序将不会跳转执行循环后面的下一条指令。

因此,我们现在有了循环的结构。下面是转换回 Go 的循环:

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

println(t)

该循环的主体是缺失的,下面是指令:

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 表示“将内存从源移动到目标”。由以下内容组成:

  • 片段 ""..autotmp_5+16(SP) 其中 SP 是堆栈指针(我们当前的内存栈帧),而 autotmp_* 是自动生成的变量名称。
  • 偏移量8(在64位架构上,int为8位)乘以寄存器AX的值,即循环中的当前位置。
  • 由寄存器DX表示的,目标现在包含循环的当前值。

然后,INCQ 代表“递增”,并将递增循环的当前位置:

循环体的最后一条指令是 ADDQ DX, CX 表示“将DX添加到CX”。之前我们已经看到DX包含循环的当前值,而CX是包含变量 t 内容的寄存器:

它将一直循环直到循环计数器到达5。然后,循环之后的指令显示寄存器CX将其值移至 t :

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

这是处于最终状态的图:

我们还可以在Go中完成循环的翻译:

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)
}

为这个新程序生成汇编代码,将提供完全相同的输出。

2改进

内部转换循环的方式可能会对其他功能(例如Go调度程序)产生影响。在Go 1.10之前,编译的循环类似于以下代码:

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)
}

这种实现方式的问题是,当达到5时,指针p超过了分配的末尾。这个问题使循环不容易被抢占,因为它的主体不安全。循环编译的优化确保它不会创建任何过去的指针。为准备Go调度程序中的非合作式抢占而进行了此改进。

总结

以上所述是小编给大家介绍的汇编分析 Golang 循环,希望对大家有所帮助,也非常感谢大家对脚本之家网站的支持!

相关文章

  • 汇编语言 寄存器内存访问原理解析

    汇编语言 寄存器内存访问原理解析

    这篇文章主要介绍了汇编语言 寄存器内存访问原理解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-01-01
  • 8086汇编开发环境搭建和Debug模式介绍(图文详解)

    8086汇编开发环境搭建和Debug模式介绍(图文详解)

    这篇文章主要介绍了8086汇编开发环境搭建和Debug模式介绍,本文图文并茂给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • 汇编语言中的segment

    汇编语言中的segment

    segment是段的意思,是段定义伪指令,一个正常的应用程序被由若干个 segment组成,接下来通过本文给大家介绍汇编语言中的segment,需要的朋友可以参考下
    2020-01-01
  • 汇编语言mov指令及基本用法

    汇编语言mov指令及基本用法

    在汇编语言中,MOV指令是数据传送指令,也是最基本的编程指令,用于将一个数据从源地址传送到目标地址(寄存器间的数据传送本质上也是一样的)。这篇文章给大家介绍汇编语言mov指令及基本用法,感兴趣的朋友一起看看吧
    2020-01-01
  • 汇编实现的memcpy和memset的方法

    汇编实现的memcpy和memset的方法

    这篇文章主要介绍了汇编实现的memcpy和memset的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-02-02
  • 汇编实现冒泡排序的方法示例

    汇编实现冒泡排序的方法示例

    这篇文章主要介绍了汇编实现冒泡排序的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 汇编语言程序设计之根据输入改变屏幕颜色的代码

    汇编语言程序设计之根据输入改变屏幕颜色的代码

    这篇文章主要介绍了汇编语言中的根据输入改变屏幕颜色的代码,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-03-03
  • 汇编语言实现在指定字符串中搜索字符''A''的方法

    汇编语言实现在指定字符串中搜索字符''A''的方法

    这篇文章主要介绍了汇编语言实现在指定字符串中搜索字符'A'的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-02-02
  • 详解汇编语言中中括号[]作用及lea和mov指令的区别

    详解汇编语言中中括号[]作用及lea和mov指令的区别

    这篇文章主要介绍了汇编语言中中括号[]作用及lea和mov指令的区别,本文分步骤给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-01-01
  • 16位汇编语言寄存器及指令整理(小结)

    16位汇编语言寄存器及指令整理(小结)

    这篇文章主要介绍了16位汇编语言寄存器及指令整理(小结),文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-01-01

最新评论