首页 > 编程语言 >golang汇编学习(寄存器)

golang汇编学习(寄存器)

时间:2023-07-02 22:33:16浏览次数:37  
标签:24 汇编 48 SP FP golang BP 寄存器 go

好久没有写博客了,上一篇写的汇编只是简单的调试了一下,这段时间又看了下,做一个简单的汇总。

两个代码

汇编代码,1_amd64.s

TEXT ·add(SB),$0-0
MOVQ a+0(FP),AX
MOVQ b+8(FP),BX
ADDQ AX,BX
MOVQ BX,c+16(FP)
RET

主函数1.go

package main

func add(a, b int) int
func main() {
    sum := add(1, 2)
    println(sum)
}

主要对这两个简单的代码进行调试,实现的功能也比较简单:计算两个数之和。

main函数的初始化

 

注意:上面的汇编代码是使用未优化的。

main函数是被系统调用的,首先将SP拉伸到40字节,然后将BP寄存器入栈,接着再调整BP到该位置,当前BP所在的位置应该算是栈空间的开始!

main函数的一些变量如何分配?

 在go语言汇编里面,当A调用B时,在A的栈上准备参数(和返回值,如果有),图示展示了这一点。main函数调用add,因此它准备了两个实参和一个返回值,一共24字节,同时还有一个局部变量sum。

可见它也没有把sum优化,也就是说本来是什么就是什么,按部就班的将各个参数和局部变量排布好。

在执行call调用时,会将PC压栈,同时SP再往下前进8字节。

1_amd64.s分析

分析完了main.go,接着看1_amd64.s文件,这部分代码是由人工写的,所以考虑的比较简单。

FP寄存器

FP伪寄存器按照书本的说法就是提供一个快捷的方式访问函数参数,它的位置应该在:

 由图可见,伪FP直接对着函数参数,因此a+0(FP)就对应实参a,b+8(FP)就对应实参b,同理,c+16(FP)就对应返回值c。

因此高亮的汇编代码意思是:

1和2搬到栈中,然后执行call调用,将结果搬到add返回值空间,再接着将该返回值复制一份到局部变量sum!

伪SP寄存器

按书本上说,伪SP寄存器对应当前栈帧的底部。此时,请读者注意,在1_amd64.s文件中,我没有进行SP的拉伸和BP的移动,因为这个代码是我写的,不是编译器写的。

因此当前相当于只移动了真SP,原因是真SP会随着call的执行必须移动。

那么这样说,意思就是进入到add函数时,当前栈的分布还是像上图一样没变化。因此当前的栈底就是真SP所在的位置。

 由于伪SP对应当前栈的栈底,因此它的一个特性是固定不变,可以用做计算局部变量的位置。

BP到底会不会压栈?

我们在X86的汇编中知道,一般情况下BP会入栈的,但是GO中似乎提到可以简化,这个问题先搁置在这里,后面再说明。

当前的1_amd64.s并没有将BP入栈,因为这是人工写的。

下面我们在程序中再写一个简单的减法函数,然后编译查看一下。

func sub(a, b int) int {
    c := a - b
    return c
}

编译之后得到:

"".sub STEXT nosplit size=52 args=0x18 locals=0x10
        0x0000 00000 (1.go:4)   TEXT    "".sub(SB), NOSPLIT|ABIInternal, $16-24
        0x0000 00000 (1.go:4)   SUBQ    $16, SP
        0x0004 00004 (1.go:4)   MOVQ    BP, 8(SP)
        0x0009 00009 (1.go:4)   LEAQ    8(SP), BP
        0x000e 00014 (1.go:4)   FUNCDATA        $0, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
        0x000e 00014 (1.go:4)   FUNCDATA        $1, gclocals·33cdeccccebe80329f1fdbee7f5874cb(SB)
        0x000e 00014 (1.go:4)   MOVQ    $0, "".~r2+40(SP)
        0x0017 00023 (1.go:5)   MOVQ    "".a+24(SP), AX
        0x001c 00028 (1.go:5)   SUBQ    "".b+32(SP), AX
        0x0021 00033 (1.go:5)   MOVQ    AX, "".c(SP)
        0x0025 00037 (1.go:6)   MOVQ    AX, "".~r2+40(SP)
        0x002a 00042 (1.go:6)   MOVQ    8(SP), BP
        0x002f 00047 (1.go:6)   ADDQ    $16, SP
        0x0033 00051 (1.go:6)   RET
        0x0000 48 83 ec 10 48 89 6c 24 08 48 8d 6c 24 08 48 c7  H...H.l$.H.l$.H.
        0x0010 44 24 28 00 00 00 00 48 8b 44 24 18 48 2b 44 24  D$(....H.D$.H+D$
        0x0020 20 48 89 04 24 48 89 44 24 28 48 8b 6c 24 08 48   H..$H.D$(H.l$.H
        0x0030 83 c4 10 c3  

从结果可以看到:BP被入栈了,这是未优化的代码

其实BP入不入栈并没有什么影响,只要计算相对位置就行

总结

这篇文章详细说明了伪SP,伪FP,BP是否入栈,以及各个参数的空间安排,了解这些细节对于常见的汇编阅读已经足够。

 

标签:24,汇编,48,SP,FP,golang,BP,寄存器,go
From: https://www.cnblogs.com/tinaluo/p/17521578.html

相关文章

  • CentOS 9 x64 使用 Nginx、Supervisor 部署 Go/Golang 服务
    前言在CentOS9x64系统上,可以通过以下步骤来部署Golang服务。1.安装必要的软件包安装以下软件包:Golang:Golang编程语言Nginx:Web服务器Supervisor:进程管理工具Git:版本控制工具EPEL:扩展软件包可以通过以下命令来安装:yum-yupdateyuminstallnginxgolangepel-......
  • CentOS 9 x64 使用 Nginx、Supervisor 部署 Go/Golang 服务
    前言在CentOS9x64系统上,可以通过以下步骤来部署Golang服务。1.安装必要的软件包安装以下软件包:Golang:Golang编程语言Nginx:Web服务器Supervisor:进程管理工具Git:版本控制工具EPEL:扩展软件包可以通过以下命令来安装:yum-yupdateyuminstallnginxgolangepel......
  • Golang实现图片与视频的缩略图生成
    图片与视频的缩略图是一个十分常见的需求,比如即时消息。这里摘取了Golang项目中的相关代码,分享图片与视频相关处理的开发经验。图片缩略图缩略图的尺寸分为两种规则:1)边长模式,生成正方形缩略图;2)宽高模式,又分三种:指定宽高、指定宽(高等比缩放)、指定高(宽等比缩放)。如果原图为png或gif,缩......
  • golang查询数据报错:closing bad idle connection: unexpected read from socket
    原因应用程序在使用驱动的有效空闲连接时候,发现数据库的连接已经失效(因为连接超过wait_timeout时间),用一个失效的连接查数据,所以报错。解决办法将sql驱动SetConnMaxLifetime和SetConnMaxIdleTime设置时间,并且小于数据库的wait_timeout时间(单位秒)。调小wait_timeout。分析......
  • 学习IDA权威指南-反汇编工具
    分类工具file通过检查文件中的某些特定字段来确认文件的类型类似的有cygwin使用cygwin工具查看结果PE-Tools用来分析windows系统中正在运行的进程和可执行文件的工具。PEID识别构建某一特定windowsPE文件二进制文件所使用的编译器。IDA 编辑器等等。工具非常多,要用到再学习使用......
  • Debug Golang源码中的单元测试
    goland配置如上,既可以debuggolang源码中的单元测试。......
  • golang之copier
    今天我们要介绍的copier库就能处理不同类型之间的赋值。除此之外,copier还能:调用同名方法为字段赋值;以源对象字段为参数调用目标对象的方法,从而为目标对象赋值(当然也可以做其它的任何事情);将切片赋值给切片(可以是不同类型哦);将结构体追加到切片中。快速使用先安装:$goget......
  • 汇编指令--pushf,popf
           ......
  • 汇编语言学习笔记
    汇编语言学习笔记目录第一章基础知识第二章寄存器(CPU工作原理)第三章寄存器(内存访问)第四章第一个程序第五章[BX]和loop指令第六章包含多个段的程序第七章更灵活定位内存地址第八章数据处理的两个基本问题第九章转移指令的原理第十章call和ret指令第十一章标......
  • Golang 简单的数据对齐可提高程序速度和内存使用率
    序Golang中的结构或struct是用户定义的类型,允许将可能不同类型的项分组/组合为单一类型。可以说是一个不支持继承但支持组合的轻量级类。我们使用Golang编写代码的时候,你肯定使用过struct。但是,你可能不知道的是,通过简单地重新排序结构中的字段,可以极大地提高Go程序的......