首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >系统架构之计算机必要前置知识

系统架构之计算机必要前置知识

作者头像
沅则
发布2026-04-13 17:37:45
发布2026-04-13 17:37:45
1000
举报
概述
现代x86 CPU可以用专门的硬件(如AVX-512指令集)一次处理512位(64字节)数据!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 计算机基础知识
    • ASCII 编码基础
    • 控制字符
    • 从 ASCII 到 UTF-8 的演变
    • UTF-8 的优势
    • 字节分组
      • 基本概念
      • 数据单位层级(从小到大)
        • 重要提醒
        • 历史背景
    • 64位计算机能表达的数字范围以及整数溢出的概念
      • 核心概念回顾
      • 64位的数值范围
      • 整数溢出(重点)
      • 现代硬件的扩展能力
      • 总结
    • 计算机如何表示负数--补码
      • 问题:怎么区分正负?
        • 最初的“笨办法”:符号位
        • 巧妙的设计:补码
      • 补码的巨大优势
      • 8位有符号数的范围
    • 多字节数据在内存中的布局
      • 核心概念:如何描述一个字节的位置
        • 1. 按“重要性”描述
        • 2. 按“左右”描述
        • 3. 按“先后”描述
      • 为什么这个概念很重要?
  • 寄存器
    • 什么是寄存器?
    • 寄存器的演进(以x86系列为例)
    • 特殊寄存器:指令指针
    • 扩展寄存器
  • 如何通过汇编指令 mov 给寄存器赋值
    • 核心指令:mov
    • 立即数
    • 操作部分寄存器
    • ⚠️ 重要注意事项:32位写操作会清零高位!
      • 示例对比:
    • 为什么这么设计?
    • 总结
    • 为什么32位写操作会清零高位?
      • 核心一句话
      • 打个比方
        • 场景1:你只动下层的一部分(16位或8位)
        • 场景2:你动整个下层(32位)
      • 为什么这么设计?
      • 对比示例
      • 简单记忆
    • 数据扩展
      • 问题场景
      • 发生了什么?
      • 问题出在哪?
      • 解决方案:movsx
      • movsx 做了什么?
      • 具体过程
      • 对比一下
      • 类似的指令
      • 总结
  • 进程内存的虚拟性和初始内容
    • 进程内存一开始装了什么?
    • 为什么都写 0x10000?
    • 虚拟内存的好处
  • 栈的基本操作:push pop
    • 1. 栈的用途
    • 2. push 示例
    • 3. x86-64 的 push 限制
    • 4. pop 示例
  • 栈的地址和增长方向
    • 栈的位置
    • 栈的增长方向
    • 为什么栈向下增长?
  • 通过 mov 指令访问虚拟内存
    • 1. 虚拟内存的陷阱
    • 2. 用 mov 读写内存
      • 示例1:从内存读到寄存器
      • 示例2:从寄存器写到内存
    • 3. push 的本质
    • 4. 内存是按字节编址的
      • 示例:
    • 总结
    • 为什么进程地址空间不从 0 开始?
      • 1. 防止空指针解引用(Null Pointer Dereference)
      • 2. 历史教训:CVE-2009-1897
      • 3. 0x10000 是常见起点
      • 总结
  • 小端序(little endian)——数据在内存里是怎么存的
    • 1. 什么是小端序?
    • 2. 示例演示
    • 3. 重要说明
    • 4. 为什么用小端序?
  • 内存地址的计算方式,以及 x86-64 里一种很有用的指令 lea(Load Effective Address)。
    • 1. 用偏移量访问内存
    • 2. 用 lea 计算地址但不访问内存
    • 3. 地址计算的格式限制
  • 程序控制流
    • 1. 标志寄存器(rflags)
    • 2. 主要标志位含义
    • 🔁 常见比较模式
      • 无符号比较
      • 有符号比较
      • 与零比较
      • 相等比较
    • 📘 常用跳转指令速查表
  • x86-64 汇编中如何用条件跳转实现循环
    • 🔁 循环的本质
    • 📘 示例:计数到 10
      • 执行过程
    • 🔧 变体:不同类型的循环
      • 1. for 风格循环(计数)
      • 2. while 风格循环(条件控制)
      • 3. 无限循环
    • 🧠 关键点总结
    • 📌 注意事项
  • x86-64 汇编中函数调用(call / ret)
    • 📞 函数调用的核心机制
    • 🔍 示例代码解析
    • 🧠 调用过程详解
      • 第一次调用
      • 第二次调用
      • 最后
    • ⚠️ 注意事项
      • 1. 返回值规范
      • 2. 参数传递
      • 3. 寄存器保存
    • 🛠 完善 EXIT 函数
  • 调用约定
    • 📌 什么是调用约定?
    • 🖥 不同架构的调用约定
      • 1. Linux x86(32位)
      • 2. Linux amd64(x86-64,笔记中的)
      • 3. Linux arm(32位)
    • 🔒 寄存器保存规则(Linux amd64)
      • 被调用者保存(callee-saved)
      • 调用者保存(caller-saved)
    • 🧠 为什么需要这些规则?
    • 📝 总结:amd64 函数调用步骤
  • System Calls
  • 1.系统调用
    • 什么是系统调用?
    • x86-64 Linux 系统调用约定
      • 寄存器分工
    • 示例详解:从键盘读取并输出
      • 第一步:读取100字节
      • 第二步:输出刚读取的内容
    • 为什么用栈(rsp)做缓冲区?
    • 完整流程
    • 常用系统调用号(Linux x86-64)
    • 逐个解释
      • 1. open
      • 2. read
      • 3. write
      • 4. fork
      • 5. execve
      • 6. wait
    • 组合起来就是完整的进程生命周期
    • 总结
    • 如何在栈上手动构造字符串,然后作为参数传给系统调用
    • 字符串在内存中的表示
    • 在栈上构造字符串
      • 代码
      • 内存布局
    • 调用 open()
      • 参数说明
      • 返回值
    • 完整流程(隐含)
    • 为什么要手动构造?
    • 查open 系统调用里的 flags 参数
      • 为什么需要“查”这些常量?
      • 怎么查?用C程序
      • open 的常用 flags 参数值
    • 程序如何主动退出,并且把退出状态返回给操作系统
    • exit 系统调用
      • 做了什么?
    • 退出码有什么用?
      • 常见惯例
      • 在 Shell 中查看
    • 为什么需要显式退出?
    • 完整程序示例
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档