64 位多处理器初始化
本文主要讲解 64 位多处理器相关的运行架构,及其初始化。
本文主要讲解 64 位多处理器相关的运行架构,及其初始化。
本文所述为操作系统在适配 64 位处理器时的一般逻辑,并不意味着某一具体操作系统的实现。
我们知道 IA-32e 架构在 64 位模式下取消了硬件任务切换,且强制使用平坦模型。这使得任务切换不再受到 CPU 规则的强约束,这使得任务切换变得更加轻量级。
本文会对 64 位模式下单核处理器的多任务管理的流程和方法做一些简要的整理。
本文主要用于梳理 x86 的指令的基本格式。
本文主要用于理顺 IA-32e 架构下的内存分配流程。
本文旨在全面回顾 x86 平台上各种分页技术的发展历程及其特点,帮助读者理解这些技术是如何逐步演进以适应不断增长的需求。
性能优化是提升用户体验和系统稳定性的关键环节,Go语言提供了两种强大的性能分析工具——pprof 和 trace,分别用于性能剖析和事件追踪。
工作原因经常需要处理手机号,一般都是用一些开源库来解析。最近看了一下开源库的实现,发现对电话号码的定义还挺复杂的。所以结合之前了解到的一些 PSTN 的知识对电话和电话号码相关的内容进行了整理。
在上篇文章说到了学习Plan 9基础可以为我们揭开底层的一些细节,从而通过实践去探究原理。接下来就以Plan 9为基础,从不同角度去探索Golang语言吧。
如果你还没有阅读Plan 9相关的知识,推荐阅读Plan9 & Go Assembler
环境说明:Mac m1 (ARM架构)、Golang v1.23.2
这里简单回顾几个比较重要的知识点吧
Plan 9汇编伪寄存器
Plan 9源操作数与目标操作数方向,源操作数在前,目的操作数在后
movl $0x2, %eax 将立即数0x2移动到eax寄存器在函数调用的时候,会经常看到这样一段的函数序言,主要的作用就是保存「调用者的」BP
pushq %rbp
movq %rsp, %rbp
subq %16, %rsp
大致步骤如下
此时函数只包含返回地址(即调用函数的下一条指令的地址)

pushq %rbp将调用者的栈帧指针(%rbp)压入栈
保存上一个栈帧的基地址,用于函数返回时恢复调用者的栈帧

moveq %rsp, %rbp将当前栈指针%rsp的值赋给%rbp, 建立当前函数的栈帧基地址 标记当前函数的栈帧起点

subq $16, %rsp
将栈指针%rsp向下移动16字节,为局部变量分配空间 完成局部变量栈空间的分配

下面就来编写代码,验证一下吧
go tool compile -S -N -l add_func.go
// base/prologue/add_func.go
package main
func add(a, b int) int {
return a + b
}
func main() {
_ = add(1, 2)
}
MOVD.W R30, -32(RSP) 保存调用者的链接寄存器(R30)到栈中。MOVD R29, -8(RSP) 保存当前帧指针(R29)到栈中。SUB $8, RSP, R29 更新栈帧指针R29。0x0000 00000 TEXT main.add(SB), NOSPLIT|LEAF|ABIInternal, $32-16
0x0000 00000 MOVD.W R30, -32(RSP)
0x0004 00004 MOVD R29, -8(RSP)
0x0008 00008 SUB $8, RSP, R29