如何在Go中使用汇编
目录
晚上课题组聚餐, 没啥心思学习了, 借助LLM简单学习了一下如何使用, 在此感谢Gemini
一些资料
之前在曹大和柴大的《Go语言高级编程》中看到有关于汇编的介绍, Go官网也有一篇文章, 网上还有一些其他的资料
为什么使用汇编
Gemini 生成
- 极致性能. (我们写的汇编不一定就能增加性能, 反而导致性能下降)
- 访问特定的CPU特性, 比如做一些硬件加解密, 随机数生成等
- 精确控制内存与寄存器
- 零拷贝处理
- 固定寄存器变量
- 系统调用与内核交互
- 自制系统调用:你可以直接通过 SYSCALL 指令与内核对话, 跳过标准库的封装
- 上下文切换:如果你在尝试实现用户态协程调度器, 手写汇编是保存和恢复寄存器上下文(Context Switch)的唯一方法
- 绕过
runtime的限制- 边界检查(很久之前看过一篇文章, 定位到热点调用之后, 在确保完全不会越界的情况下, 直接使用汇编实现)
- 逃避栈溢出检查
- …
实现一个简单的Add
与平常的函数/方法不同, 我们只需要声明一个函数即可, 不需要函数体/方法体
main.go
func Add(a, b int64) int64接下来在当前目录下新建一个 .s 结尾的文件, 关于具体的语法可以参考文档或者交给LLM
add_amd64.s
| |
然后直接编译/运行即可: go run .
尝试使用SIMD指令
SIMD指令可以用来进行并行计算, 例如对两个向量进行加法运算, 可以使用SIMD指令来并行计算, 从而提高计算效率, 下面的代码是直接相加, 不考虑溢出,
并且这个场景可能也不合理, 但目的只是为了演示如何使用SIMD指令
下面只是用来演示
main.go
| |
同理可以新建一个 .s 结尾的文件, 或者用刚才的 add_amd64.s 文件也可以, 对文件名不挑剔, 但要求汇编中有我们定义的函数
add_amd64.s
| |