返回首页
苏宁会员
购物车 0
易付宝
手机苏宁

服务体验

店铺评分与同行业相比

用户评价:----

物流时效:----

售后服务:----

  • 服务承诺: 正品保障
  • 公司名称:
  • 所 在 地:

  • 正版 ARM64体系结构编程与实践(安谋科技教育计划推荐教材) 奔跑
  • 新华书店旗下自营,正版全新
    • 作者: 奔跑吧Linux社区著 | 奔跑吧Linux社区编 | 奔跑吧Linux社区译 | 奔跑吧Linux社区绘
    • 出版社: 人民邮电出版社
    • 出版时间:2021-08-01
    送至
  • 由""直接销售和发货,并提供售后服务
  • 加入购物车 购买电子书
    服务

    看了又看

    商品预定流程:

    查看大图
    /
    ×

    苏宁商家

    商家:
    美阅书店
    联系:
    • 商品

    • 服务

    • 物流

    搜索店内商品

    商品参数
    • 作者: 奔跑吧Linux社区著| 奔跑吧Linux社区编| 奔跑吧Linux社区译| 奔跑吧Linux社区绘
    • 出版社:人民邮电出版社
    • 出版时间:2021-08-01
    • 版次:null
    • 印次:1
    • 字数:731.0
    • 页数:432
    • 开本:16开
    • ISBN:9787115582102
    • 版权提供:人民邮电出版社
    • 作者:奔跑吧Linux社区
    • 著:奔跑吧Linux社区
    • 装帧:平装
    • 印次:1
    • 定价:119.80
    • ISBN:9787115582102
    • 出版社:人民邮电出版社
    • 开本:16开
    • 印刷时间:暂无
    • 语种:暂无
    • 出版时间:2021-08-01
    • 页数:432
    • 外部编号:11499209
    • 版次:null
    • 成品尺寸:暂无

    目 录
    第 1章 ARM64体系结构基础知识 1
    1.1 ARM介绍 1
    1.2 ARMv8体系结构基础知识 2
    1.2.1 ARMv8体系结构 2
    1.2.2 采用ARMv8体系结构的常见处理器内核 3
    1.2.3 ARMv8体系结构中的基本概念 3
    1.2.4 A64指令集 4
    1.2.5 ARMv8处理器执行状态 4
    1.2.6 ARMv8支持的数据宽度 5
    1.3 ARMv8寄存器 5
    1.3.1 通用寄存器 5
    1.3.2 处理器状态 6
    1.3.3 特殊寄存器 7
    1.3.4 系统寄存器 10
    1.4 Cortex-A72处理器介绍 10
    1.5 ARMv9体系结构介绍 13
    第 2章 搭建树莓派实验环境 14
    2.1 树莓派介绍 14
    2.2 搭建树莓派实验环境 15
    2.2.1 配置串口线 16
    2.2.2 安装树莓派官方OS 18
    2.2.3 实验2-1:输出“Welcome BenOS!” 19
    2.2.4 实验2-2:使用GDB与QEMU虚拟机调试BenOS 20
    2.2.5 实验2-3:使用J-Link EDU仿真器调试树莓派 21
    2.3 BenOS基础实验代码解析 27
    2.4 QEMU虚拟机与ARM64实验平台 32
    第3章 A64指令集1——加载与存储指令 35
    3.1 A64指令集介绍 36
    3.2 A64指令编码格式 37
    3.3 加载与存储指令 38
    3.3.1 基于基地址的寻址模式 39
    3.3.2 变基模式 41
    3.3.3 PC相对地址模式 42
    3.3.4 LDR伪指令 43
    3.4 加载与存储指令的变种 44
    3.4.1 不同位宽的加载与存储指令 44
    3.4.2 不可扩展的加载和存储指令 45
    3.4.3 多字节内存加载和存储指令 46
    3.4.4 独占内存访问指令 48
    3.4.5 隐含加载-获取/存储-释放
    内存屏障原语 48
    3.4.6 非特权访问级别的加载和存储指令 48
    3.5 入栈与出栈 49
    3.6 MOV指令 51
    3.7 陷阱:你用对加载与存储指令了吗 52
    3.8 实验 53
    3.8.1 实验3-1:熟悉MOV和LDR指令 53
    3.8.2 实验3-2:前变基与后变基寻址模式1 53
    3.8.3 实验3-3:前变基与后变基寻址模式2 54
    3.8.4 实验3-4:PC相对地址寻址 54
    3.8.5 实验3-5:memcpy()函数的实现 54
    3.8.6 实验3-6:LDP和STP指令的使用 55
    第4章 A64指令集2——算术与移位指令 56
    4.1 条件操作码 57
    4.2 加法与减法指令 57
    4.2.1 ADD指令 58
    4.2.2 ADDS指令 60
    4.2.3 ADC指令 61
    4.2.4 SUB指令 61
    4.2.5 SUBS指令 64
    4.2.6 SBC指令 64
    4.3 CMP指令 65
    4.4 关于条件标志位的示例 67
    4.5 移位指令 68
    4.6 位操作指令 68
    4.6.1 与操作指令 68
    4.6.2 或操作指令 69
    4.6.3 位清除操作指令 71
    4.6.4 CLZ指令 71
    4.7 位段操作指令 71
    4.7.1 位段插入操作指令 71
    4.7.2 位段提取操作指令 72
    4.8 实验 73
    4.8.1 实验4-1:测试ADDS和CMP指令的C标志位 73
    4.8.2 实验4-2:条件标志位的使用 74
    4.8.3 实验4-3:测试ANDS指令以及Z标志位 74
    4.8.4 实验4-4:测试位段操作指令 74
    4.8.5 实验4-5:使用位段指令来读取寄存器 74
    第5章 A64指令集3——比较指令与跳转指令 76
    5.1 比较指令 76
    5.1.1 CMN指令 76
    5.1.2 CSEL指令 77
    5.1.3 CSET指令 78
    5.1.4 CSINC指令 78
    5.2 跳转与返回指令 79
    5.2.1 跳转指令 79
    5.2.2 返回指令 80
    5.2.3 比较并跳转指令 80
    5.3 陷阱:为什么在RET指令之后系统就崩溃了 80
    5.4 实验 82
    5.4.1 实验5-1:CMP和CMN指令 82
    5.4.2 实验5-2:条件选择指令 82
    5.4.3 实验5-3:子函数跳转 82
    第6章 A64指令集4——其他重要指令 83
    6.1 PC相对地址加载指令 83
    6.2 LDR和ADRP指令的区别 85
    6.3 内存独占访问指令 85
    6.4 异常处理指令 86
    6.5 系统寄存器访问指令 87
    6.6 内存屏障指令 88
    6.7 实验 88
    6.7.1 实验6-1:测试ADRP和LDR伪指令 88
    6.7.2 实验6-2:ADRP和LDR伪指令的陷阱 89
    6.7.3 实验6-3:LDXR和STXR指令的使用1 90
    6.7.4 实验6-4:LDXR和STXR指令的使用2 90
    第7章 A64指令集的陷阱 91
    7.1 案例7-1:加载宏标签 91
    7.2 案例7-2:加载字符串 92
    7.3 案例7-3:读写寄存器导致树莓派4B死机 93
    7.4 案例7-4:LDXR指令导致树莓派4B死机 94
    7.5 汇编大作业7-1:在汇编中实现串口输出功能 95
    7.6 汇编大作业7-2:分析Linux 5.0的启动汇编代码 95
    第8章 GNU汇编器 96
    8.1 编译流程与ELF文件 97
    8.2 一个简单的汇编程序 99
    8.3 汇编语法 102
    8.3.1 注释 102
    8.3.2 符号 102
    8.4 常用的伪指令 103
    8.4.1 对齐伪指令 103
    8.4.2 数据定义伪指令 103
    8.4.3 与函数相关的伪指令 104
    8.4.4 与段相关的伪指令 105
    8.4.5 与宏相关的伪指令 106
    8.5 AArch64依赖特性 108
    8.5.1 AArch64特有的命令行选项 108
    8.5.2 语法 108
    8.5.3 AArch64特有的伪指令 109
    8.5.4 LDR伪指令 109
    8.6 实验 110
    8.6.1 实验8-1:汇编语言练习——求最大数 110
    8.6.2 实验8-2:汇编语言练习——通过C语言调用汇编函数 110
    8.6.3 实验8-3:汇编语言练习——通过汇编语言调用C函数 110
    8.6.4 实验8-4:使用汇编伪操作来实现一张表 110
    8.6.5 实验8-5:汇编宏的使用 111
    第9章 链接器与链接脚本 112
    9.1 链接器介绍 112
    9.2 链接脚本 114
    9.2.1 一个简单的链接程序 114
    9.2.2 设置入口点 115
    9.2.3 基本概念 115
    9.2.4 符号赋值与引用 115
    9.2.5 当前位置计数器 117
    9.2.6 SECTIONS命令 117
    9.2.7 常用的内建函数 120
    9.3 重定位 121
    9.3.1 BenOS重定位 121
    9.3.2 UBoot和Linux内核重定位 124
    9.4 实验 126
    9.4.1 实验9-1:分析链接脚本文件 126
    9.4.2 实验9-2:输出每个段的内存布局 127
    9.4.3 实验9-3:加载地址不等于运行地址 127
    9.4.4 实验9-4:分析Linux 5.0内核的链接脚本文件 127
    第 10章 GCC内嵌汇编代码 128
    10.1 内嵌汇编代码基本用法 128
    10.1.1 基础内嵌汇编代码 128
    10.1.2 扩展内嵌汇编代码 128
    10.1.3 内嵌汇编代码的修饰符和约束符 130
    10.1.4 使用汇编符号名 132
    10.1.5 内嵌汇编函数与宏的结合 133
    10.1.6 使用goto修饰词 133
    10.2 案例分析 134
    10.3 实验 138
    10.3.1 实验10-1:实现简单的memcpy 函数 138
    10.3.2 实验10-2:使用汇编符号名编写内嵌汇编代码 138
    10.3.3 实验10-3:使用内嵌汇编代码完善__memset_16bytes 汇编函数 138
    10.3.4 实验10-4:使用内嵌汇编代码与宏 138
    10.3.5 实验10-5:实现读和写系统寄存器的宏 139
    10.3.6 实验10-6:goto模板的内嵌汇编函数 139
    第 11章 异常处理 140
    11.1 异常处理的基本概念 140
    11.1.1 异常类型 140
    11.1.2 异常等级 141
    11.1.3 同步异常和异步异常 141
    11.2 异常处理与返回 142
    11.2.1 异常入口 142
    11.2.2 异常返回 142
    11.2.3 异常返回地址 143
    11.2.4 异常处理路由 143
    11.2.5 栈的选择 145
    11.2.6 异常处理的执行状态 145
    11.2.7 异常返回的执行状态 146
    11.3 异常向量表 146
    11.3.1 ARMv8异常向量表 146
    11.3.2 Linux 5.0内核的异常向量表 147
    11.3.3 VBAR_ELx 148
    11.4 异常现场 149
    11.5 同步异常的解析 149
    11.5.1 异常类型 150
    11.5.2 数据异常 151
    11.6 案例分析 153
    11.6.1 从EL2切换到EL1 153
    11.6.2 指令不对齐的同步异常处理 154
    11.7 实验 156
    11.7.1 实验11-1:切换到EL1 156
    11.7.2 实验11-2:建立异常向量表 157
    11.7.3 实验11-3:寻找树莓派4B上触发异常的指令 157
    11.7.4 实验11-4:解析数据异常的信息 158
    第 12章 中断处理 159
    12.1 中断处理背景知识 159
    12.1.1 中断引脚 159
    12.1.2 中断控制器 159
    12.1.3 中断处理过程 160
    12.2 树莓派4B上的传统中断控制器 160
    12.3 ARM内核上的通用定时器 163
    12.4 中断现场 165
    12.4.1 保存中断现场 165
    12.4.2 恢复中断现场 165
    12.5 案例分析:在树莓派4B上实现 一个定时器 166
    12.5.1 中断现场的保存 166
    12.5.2 修改异常向量表 169
    12.5.3 通用定时器初始化 170
    12.5.4 IRQ处理 170
    12.5.5 打开本地中断 171
    12.6 实验 172
    12.6.1 实验12-1:在树莓派4B上 实现通用定时器中断 172
    12.6.2 实验12-2:使用汇编函数保存和恢复中断现场 173
    第 13章 GIC-V2 174
    13.1 GIC发展历史 174
    13.2 中断状态、中断触发方式和 硬件中断号 175
    13.3 GIC-V2 175
    13.3.1 GIC-V2概要 175
    13.3.2 GIC-V2内部结构 176
    13.3.3 中断流程 176
    13.3.4 GIC-V2寄存器 178
    13.3.5 中断路由 179
    13.4 树莓派4B上的GIC-400 180
    13.4.1 中断号分配 180
    13.4.2 访问GIC-400寄存器 181
    13.4.3 中断处理流程 181
    13.5 实验 182
    13.5.1 实验13-1:实现通用定时器中断 182
    13.5.2 实验13-2:实现树莓派4B上的系统定时器 183
    第 14章 内存管理 184
    14.1 内存管理基础知识 184
    14.1.1 内存管理的“远古时代” 184
    14.1.2 地址空间的抽象 186
    14.1.3 分段机制 187
    14.1.4 分页机制 187
    14.2 ARM64内存管理 190
    14.2.1 页表 192
    14.2.2 页表映射 192
    14.2.3 页面粒度 194
    14.2.4 两套页表 195
    14.2.5 页表项描述符 196
    14.2.6 页表属性 198
    14.2.7 连续块表项 201
    14.3 硬件管理访问位和脏位 201
    14.3.1 访问位的硬件管理机制 201
    14.3.2 脏位的硬件管理机制 201
    14.4 与地址转换相关的控制寄存器 202
    14.4.1 TCR 202
    14.4.2 SCTLR 204
    14.4.3 TTBR 204
    14.5 内存属性 204
    14.5.1 普通类型内存 204
    14.5.2 设备类型内存 204
    14.6 案例分析:在BenOS里实现恒等映射 207
    14.6.1 页表定义 208
    14.6.2 页表数据结构 211
    14.6.3 创建页表 211
    14.6.4 打开MMU 217
    14.6.5 测试MMU 218
    14.7 实验 220
    14.7.1 实验14-1:建立恒等映射 220
    14.7.2 实验14-2:为什么MMU 无法运行 220
    14.7.3 实验14-3:实现一个 MMU页表的转储功能 220
    14.7.4 实验14-4:修改页面属性导致的系统死机 221
    14.7.5 实验14-5:使用汇编语言来建立恒等映射和打开MMU 222
    14.7.6 实验14-6:验证LDXR和 STXR指令 222
    14.7.7 实验14-7:AT指令 223
    第 15章 高速缓存基础知识 224
    15.1 为什么需要高速缓存 224
    15.2 高速缓存的访问延时 225
    15.3 高速缓存的工作原理 227
    15.4 高速缓存的映射方式 229
    15.4.1 直接映射 229
    15.4.2 全相连映射 230
    15.4.3 组相连映射 230
    15.4.4 组相连的高速缓存的例子 231
    15.5 虚拟高速缓存与物理高速缓存 232
    15.5.1 物理高速缓存 232
    15.5.2 虚拟高速缓存 232
    15.5.3 VIPT和PIPT 232
    15.6 重名和同名问题 233
    15.6.1 重名问题 233
    15.6.2 同名问题 234
    15.6.3 VIPT产生的重名问题 235
    15.7 高速缓存策略 236
    15.8 高速缓存的共享属性 238
    15.8.1 共享属性 238
    15.8.2 PoU和PoC的区别 239
    15.9 高速缓存的维护指令 241
    15.10 高速缓存枚举 242
    15.11 实验 245
    15.11.1 实验15-1:枚举高速缓存 245
    15.11.2 实验15-2:清理高速缓存 245
    第 16章 缓存一致性 246
    16.1 为什么需要缓存一致性 246
    16.2 缓存一致性的分类 247
    16.2.1 ARM处理器缓存一致性发展历程 247
    16.2.2 缓存一致性分类 248
    16.2.3 系统缓存一致性问题 249
    16.3 缓存一致性的解决方案 250
    16.3.1 关闭高速缓存 250
    16.3.2 软件维护缓存一致性 250
    16.3.3 硬件维护缓存一致性 250
    16.4 MESI协议 251
    16.4.1 MESI协议简介 252
    16.4.2 本地读写与总线操作 252
    16.4.3 MESI状态转换图 253
    16.4.4 初始状态为I 253
    16.4.5 初始状态为M 256
    16.4.6 初始状态为S 257
    16.4.7 初始状态为E 258
    16.4.8 总结与案例分析 258
    16.4.9 MOESI协议 260
    16.5 高速缓存伪共享 261
    16.6 CCI和CCN缓存一致性控制器 262
    16.6.1 CCI缓存一致性控制器 262
    16.6.2 CCN缓存一致性控制器 263
    16.7 案例分析16-1:伪共享的避免 264
    16.8 案例分析16-2:DMA和 高速缓存的一致性 265
    16.8.1 从内存到设备的 FIFO缓冲区 266
    16.8.2 从设备的FIFO缓冲区到 内存 266
    16.9 案例分析16-3:自修改代码的 一致性 267
    16.10 实验 268
    16.10.1 实验16-1:高速缓存伪共享 268
    16.10.2 实验16-2:使用Perf C2C 发现高速缓存伪共享 268
    第 17章 TLB管理 269
    17.1 TLB基础知识 270
    17.2 TLB重名与同名问题 273
    17.2.1 重名问题 273
    17.2.2 同名问题 274
    17.3 ASID 274
    17.4 TLB管理指令 276
    17.4.1 TLB维护指令介绍 277
    17.4.2 TLB广播 278
    17.4.3 TLB维护指令的执行次序 278
    17.5 TLB案例分析 278
    17.5.1 TLB在Linux内核中的应用 278
    17.5.2 ASID在Linux内核中的应用 281
    17.5.3 Linux内核中的TLB 维护操作 282
    17.5.4 BBM机制 284
    第 18章 内存屏障指令 287
    18.1 内存屏障指令产生的原因 287
    18.1.1 顺序一致性内存模型 288
    18.1.2 处理器一致性内存模型 289
    18.1.3 弱一致性内存模型 289
    18.1.4 ARM64处理器的内存模型 290
    18.2 ARM64中的内存屏障指令 290
    18.2.1 使用内存屏障指令的场景 290
    18.2.2 ARM64里的内存屏障指令 291
    18.2.3 DMB指令 291
    18.2.4 DSB指令 293
    18.2.5 DMB和DSB指令的参数 294
    18.2.6 单方向内存屏障原语 294
    18.2.7 ISB指令 297
    18.2.8 高速缓存维护指令与内存屏障指令 299
    18.3 案例分析 300
    18.3.1 消息传递问题 301
    18.3.2 单方向内存屏障与自旋锁 302
    18.3.3 邮箱传递消息 304
    18.3.4 与数据高速缓存相关的案例 305
    18.3.5 与指令高速缓存相关的案例 307
    18.3.6 与TLB相关的案例 309
    18.3.7 DMA案例 310
    18.3.8 Linux内核中使指令高速缓存失效 310
    第 19章 合理使用内存屏障指令 312
    19.1 存储缓冲区与写内存屏障指令 313
    19.2 无效队列与读内存屏障指令 318
    19.3 内存屏障指令总结 321
    19.4 ARM64的内存屏障指令的区别 322
    19.5 案例分析:Linux内核中的内存屏障指令 323
    19.5.1 第 一次使用内存屏障指令 324
    19.5.2 第二次使用内存屏障指令 326
    19.5.3 第三次使用内存屏障指令 329
    19.5.4 第四次使用内存屏障指令 330
    19.5.5 总结:内存屏障指令的使用 331
    第 20章 原子操作 332
    20.1 原子操作介绍 332
    20.2 独占内存访问指令 333
    20.3 独占内存访问工作原理 334
    20.3.1 独占监视器 334
    20.3.2 独占监视器与缓存一致性 336
    20.3.3 独占监视器的粒度 338
    20.4 原子内存访问操作指令 338
    20.5 比较并交换指令 341
    20.6 WFE指令在自旋锁中的应用 342
    第 21章 操作系统相关话题 344
    21.1 C语言常见陷阱 344
    21.1.1 数据模型 344
    21.1.2 数据类型转换与整型提升 346
    21.1.3 移位操作 348
    21.2 函数调用标准 349
    21.3 栈布局 351
    21.4 创建进程 352
    21.4.1 进程控制块 352
    21.4.2 0号进程 353
    21.4.3 do_fork函数的实现 354
    21.4.4 进程上下文切换 355
    21.4.5 新进程的第 一次执行 357
    21.5 简易进程调度器 357
    21.5.1 扩展进程控制块 358
    21.5.2 就绪队列run_queue 358
    21.5.3 调度队列类 358
    21.5.4 简易调度器的实现 360
    21.5.5 自愿调度 360
    21.5.6 抢占调度 362
    21.5.7 测试用例 363
    21.6 系统调用 364
    21.6.1 系统调用介绍 364
    21.6.2 用户态调用SVC指令 364
    21.6.3 内核态对系统调用的处理 365
    21.6.4 系统调用表 366
    21.7 系统启动 367
    21.8 实验 368
    21.8.1 实验21-1:观察栈布局 368
    21.8.2 实验21-2:进程创建 369
    21.8.3 实验21-3:进程调度 369
    21.8.4 实验21-4:新增一个 malloc()系统调用 369
    21.8.5 实验21-5:新增一个clone() 系统调用 370
    第 22章 浮点运算与NEON指令 371
    22.1 数据模型 371
    22.2 浮点运算 373
    22.2.1 浮点数 373
    22.2.2 浮点控制寄存器与浮点状态寄存器 375
    22.2.3 浮点数的条件操作码 377
    22.2.4 常用浮点运算指令 377
    22.3 NEON指令集 378
    22.3.1 SISD和SIMD 378
    22.3.2 矢量运算与标量运算 379
    22.3.3 加载与存储指令LD1与 ST1 380
    22.3.4 加载与存储指令LD2和 ST2 382
    22.3.5 加载与存储指令LD3和 ST3 383
    22.3.6 加载与存储指令LD4和 ST4 385
    22.3.7 加载指令的特殊用法 385
    22.3.8 搬移指令 386
    22.3.9 反转指令 388
    22.3.10 提取指令 389
    22.3.11 交错变换指令 390
    22.3.12 查表指令 391
    22.3.13 乘加指令 391
    22.3.14 矢量算术指令 393
    22.4 案例分析22-1:RGB24转BGR24 …..393
    22.4.1 使用C语言实现RGB24转 BGR24 394
    22.4.2 手工编写NEON汇编函数 394
    22.4.3 使用NEON内建函数 395
    22.4.4 测试 395
    22.5 案例分析22-2:4×4矩阵乘法运算 397
    22.5.1 使用C语言实现4×4矩阵乘法运算 397
    22.5.2 手工编写NEON汇编函数 398
    22.5.3 使用NEON内建函数 401
    22.5.4 测试 403
    22.6 自动矢量优化 404
    22.7 实验 406
    22.7.1 实验22-1:浮点运算 406
    22.7.2 实验22-2:RGB24转BGR32…… 407
    22.7.3 实验22-3:8×8矩阵乘法 运算….. 407
    第 23章 可伸缩矢量计算与优化 408
    23.1 SVE指令介绍 408
    23.1.1 SVE寄存器组 408
    23.1.2 SVE指令语法 410
    23.2 搭建SVE运行和调试环境 410
    23.3 SVE特有的编程模式 412
    23.3.1 断言指令 412
    23.3.2 聚合加载和离散存储 414
    23.3.3 基于断言的循环控制 415
    23.3.4 基于软件推测的向量分区 421
    23.4 SVE与SVE2指令集 422
    23.5 案例分析23-1:使用SVE指令优化strcmp()函数 422
    23.5.1 使用纯汇编方式 423
    23.5.2 测试 425
    23.6 案例分析23-2:RGB24转BGR24 ….425
    23.6.1 使用纯汇编方式 426
    23.6.2 使用内嵌汇编方式 426
    23.6.3 测试 427
    23.7 案例分析23-3:4×4矩阵乘法运算 428
    23.7.1 使用内嵌汇编方式 428
    23.7.2 测试 430
    23.8 实验 431
    23.8.1 实验23-1:RGB24转BGR32 431
    23.8.2 实验23-2:8×8矩阵乘法运算 432
    23.8.3 实验23-3:使用SVE指令优化strcpy()函数 432

    奔跑吧Linux社区 由一群志同道合的工程师组成,致力于Linux等开源软件与推广,为广大工程师和读者提供深入的开源知识分享。

    1.内容系统,突出动手实践基于树莓派4B开发板,系统介绍ARM64体系结构,内容由浅入深,帮助读者开发运行小型的OS2.以问题为导向,提高学习效率 深入浅出的问题导向式学习方法,各大公司高频面试题,提高读者阅读兴趣3.趣味案例,常见陷阱总结 基于树莓派4B开发板和QEMU实验平台,总结了众多一线工程师在实际项目中遇到的陷阱与经验,让你不再害怕踩雷4.海量资源随书赠送 本书赠送配套VMware开发环境,Linux软件包,QEMU+ARM64实验平台仓库,芯片资料,实验参考代码和配套资料以及配套教学视频供读者参考学习

    目 录 第 1章 ARM64体系结构基础知识 1 1.1 ARM介绍 1 1.2 ARMv8体系结构基础知识 2 1.2.1 ARMv8体系结构 2 1.2.2 采用ARMv8体系结构的常见处理器内核 3 1.2.3 ARMv8体系结构中的基本概念 3 1.2.4 A64指令集 4 1.2.5 ARMv8处理器执行状态 4 1.2.6 ARMv8支持的数据宽度 5 1.3 ARMv8寄存器 5 1.3.1 通用寄存器 5 1.3.2 处理器状态 6 1.3.3 特殊寄存器 7 1.3.4 系统寄存器 10 1.4 Cortex-A72处理器介绍 10 1.5 ARMv9体系结构介绍 13 第 2章 搭建树莓派实验环境 14 2.1 树莓派介绍 14 2.2 搭建树莓派实验环境 15 2.2.1 配置串口线 16 2.2.2 安装树莓派官方OS 18 2.2.3 实验2-1:输出“Welcome BenOS!” 19 2.2.4 实验2-2:使用GDB与QEMU虚拟机调试BenOS 20 2.2.5 实验2-3:使用J-Link EDU器调试树莓派 21 2.3 BenOS基础实验代码解析 27 2.4 QEMU虚拟机与ARM64实验平台 32 第3章 A64指令集1——加载与存储指令 35 3.1 A64指令集介绍 36 3.2 A64指令编码格式 37 3.3 加载与存储指令 38 3.3.1 基于基地址的寻址模式 39 3.3.2 变基模式 41 3.3.3 PC相对地址模式 42 3.3.4 LDR伪指令 43 3.4 加载与存储指令的变种 44 3.4.1 不同位宽的加载与存储指令 44 3.4.2 不可扩展的加载和存储指令 45 3.4.3 多字节内存加载和存储指令 46 3.4.4 独占内存访问指令 48 3.4.5 隐含加载-获取/存储-释放 内存屏障原语 48 3.4.6 非特权访问级别的加载和存储指令 48 3.5 入栈与出栈 49 3.6 MOV指令 51 3.7 陷阱:你用对加载与存储指令了吗 52 3.8 实验 53 3.8.1 实验3-1:熟悉MOV和LDR指令 53 3.8.2 实验3-2:前变基与后变基寻址模式1 53 3.8.3 实验3-3:前变基与后变基寻址模式2 54 3.8.4 实验3-4:PC相对地址寻址 54 3.8.5 实验3-5:memcpy()函数的实现 54 3.8.6 实验3-6:LDP和STP指令的使用 55 第4章 A64指令集2——算术与移位指令 56 4.1 条件操作码 57 4.2 加法与减法指令 57 4.2.1 ADD指令 58 4.2.2 ADDS指令 60 4.2.3 ADC指令 61 4.2.4 SUB指令 61 4.2.5 SUBS指令 64 4.2.6 SBC指令 64 4.3 CMP指令 65 4.4 关于条件标志位的示例 67 4.5 移位指令 68 4.6 位操作指令 68 4.6.1 与操作指令 68 4.6.2 或操作指令 69 4.6.3 位清除操作指令 71 4.6.4 CLZ指令 71 4.7 位段操作指令 71 4.7.1 位段插入操作指令 71 4.7.2 位段提取操作指令 72 4.8 实验 73 4.8.1 实验4-1:测试ADDS和CMP指令的C标志位 73 4.8.2 实验4-2:条件标志位的使用 74 4.8.3 实验4-3:测试ANDS指令以及Z标志位 74 4.8.4 实验4-4:测试位段操作指令 74 4.8.5 实验4-5:使用位段指令来读取寄存器 74 第5章 A64指令集3——比较指令与跳转指令 76 5.1 比较指令 76 5.1.1 CMN指令 76 5.1.2 CSEL指令 77 5.1.3 CSET指令 78 5.1.4 CSINC指令 78 5.2 跳转与返回指令 79 5.2.1 跳转指令 79 5.2.2 返回指令 80 5.2.3 比较并跳转指令 80 5.3 陷阱:为什么在RET指令之后系统崩溃了 80 5.4 实验 82 5.4.1 实验5-1:CMP和CMN指令 82 5.4.2 实验5-2:条件选择指令 82 5.4.3 实验5-3:子函数跳转 82 第6章 A64指令集4——其他重要指令 83 6.1 PC相对地址加载指令 83 6.2 LDR和ADRP指令的区别 85 6.3 内存独占访问指令 85 6.4 异常处理指令 86 6.5 系统寄存器访问指令 87 6.6 内存屏障指令 88 6.7 实验 88 6.7.1 实验6-1:测试ADRP和LDR伪指令 88 6.7.2 实验6-2:ADRP和LDR伪指令的陷阱 89 6.7.3 实验6-3:LDXR和STXR指令的使用1 90 6.7.4 实验6-4:LDXR和STXR指令的使用2 90 第7章 A64指令集的陷阱 91 7.1 案例7-1:加载宏标签 91 7.2 案例7-2:加载字符串 92 7.3 案例7-3:读写寄存器导致树莓派4B死机 93 7.4 案例7-4:LDXR指令导致树莓派4B死机 94 7.5 汇编大作业7-1:在汇编中实现串口输能 95 7.6 汇编大作业7-2:分析Linux 5.0的启动汇编代码 95 第8章 GNU汇编器 96 8.1 编译流程与ELF文件 97 8.2 一个简单的汇编程序 99 8.3 汇编语法 102 8.3.1 注释 102 8.3.2 符号 102 8.4 指令 103 8.4.1 对齐伪指令 103 8.4.2 数据定义伪指令 103 8.4.3 与函数相关的伪指令 104 8.4.4 与段相关的伪指令 105 8.4.5 与宏相关的伪指令 106 8.5 AArch64依赖特 108 8.5.1 AArch64特有的命令行选项 108 8.5.2 语法 108 8.5.3 AArch64特有的伪指令 109 8.5.4 LDR伪指令 109 8.6 实验 110 8.6.1 实验8-1:汇编语言练习——求数 110 8.6.2 实验8-2:汇编语言练习——通过C语言调用汇编函数 110 8.6.3 实验8-3:汇编语言练习——通过汇编语言调用C函数 110 8.6.4 实验8-4:使用汇编伪操作来实现一张表 110 8.6.5 实验8-5:汇编宏的使用 111 第9章 链接器与链接脚本 112 9.1 链接器介绍 112 9.2 链接脚本 114 9.2.1 一个简单的链接程序 114 9.2.2 设置入口点 115 9.2.3 基本概念 115 9.2.4 符号赋值与引用 115 9.2.5 当前位置计数器 117 9.2.6 SECTIONS命令 117 9.2.7 常用的内建函数 120 9.3 重定位 121 9.3.1 BenOS重定位 121 9.3.2 UBoot和Linux内核重定位 124 9.4 实验 126 9.4.1 实验9-1:分析链接脚本文件 126 9.4.2 实验9-2:输出每个段的内存布局 127 9.4.3 实验9-3:加载地址不等于运行地址 127 9.4.4 实验9-4:分析Linux 5.0内核的链接脚本文件 127 第 10章 GCC内嵌汇编代码 128 10.1 内嵌汇编代码基本用法 128 10.1.1 基础内嵌汇编代码 128 10.1.2 扩展内嵌汇编代码 128 10.1.3 内嵌汇编代码的修饰符和约束符 130 10.1.4 使用汇编符号名 132 10.1.5 内嵌汇编函数与宏的结合 133 10.1.6 使用goto修饰词 133 10.2 案例分析 134 10.3 实验 138 10.3.1 实验10-1:实现简单的memcpy 函数 138 10.3.2 实验10-2:使用汇编符号名编写内嵌汇编代码 138 10.3.3 实验10-3:使用内嵌汇编代码完善__memset_16bytes 汇编函数 138 10.3.4 实验10-4:使用内嵌汇编代码与宏 138 10.3.5 实验10-5:实现读和写系统寄存器的宏 139 10.3.6 实验10-6:goto模板的内嵌汇编函数 139 第 11章 异常处理 140 11.1 异常处理的基本概念 140 11.1.1 异常类型 140 11.1.2 异常等级 141 11.1.3 同步异常和异步异常 141 11.2 异常处理与返回 142 11.2.1 异常入口 142 11.2.2 异常返回 142 11.2.3 异常返回地址 143 11.2.4 异常处理路由 143 11.2.5 栈的选择 145 11.2.6 异常处理的执行状态 145 11.2.7 异常返回的执行状态 146 11.3 异常向量表 146 11.3.1 ARMv8异常向量表 146 11.3.2 Linux 5.0内核的异常向量表 147 11.3.3 VBAR_ELx 148 11.4 异常现场 149 11.5 同步异常的解析 149 11.5.1 异常类型 150 11.5.2 数据异常 151 11.6 案例分析 153 11.6.1 从EL2切换到EL1 153 11.6.2 指令不对齐的同步异常处理 154 11.7 实验 156 11.7.1 实验11-1:切换到EL1 156 11.7.2 实验11-2:建立异常向量表 157 11.7.3 实验11-3:寻找树莓派4B上触发异常的指令 157 11.7.4 实验11-4:解析数据异常的信息 158 第 12章 中断处理 159 12.1 中断处理背景知识 159 12.1.1 中断引脚 159 12.1.2 中断控制器 159 12.1.3 中断处理过程 160 12.2 树莓派4B上的传统中断控制器 160 12.3 ARM内核上的通用定时器 163 12.4 中断现场 165 12.4.1 保存中断现场 165 12.4.2 恢复中断现场 165 12.5 案例分析:在树莓派4B上实现 一个定时器 166 12.5.1 中断现场的保存 166 12.5.2 修改异常向量表 169 12.5.3 通用定时器初始化 170 12.5.4 IRQ处理 170 12.5.5 打开本地中断 171 12.6 实验 172 12.6.1 实验12-1:在树莓派4B上 实现通用定时器中断 172 12.6.2 实验12-2:使用汇编函数保存和恢复中断现场 173 第 13章 GIC-V2 174 13.1 GIC发展历史 174 13.2 中断状态、中断触发方式和 硬件中断号 175 13.3 GIC-V2 175 13.3.1 GIC-V2概要 175 13.3.2 GIC-V2内部结构 176 13.3.3 中断流程 176 13.3.4 GIC-V2寄存器 178 13.3.5 中断路由 179 13.4 树莓派4B上的GIC-400 180 13.4.1 中断号分配 180 13.4.2 访问GIC-400寄存器 181 13.4.3 中断处理流程 181 13.5 实验 182 13.5.1 实验13-1:实现通用定时器中断 182 13.5.2 实验13-2:实现树莓派4B上的系统定时器 183 第 14章 内存管理 184 14.1 内存管理基础知识 184 14.1.1 内存管理的“远古时代” 184 14.1.2 地址空间的抽象 186 14.1.3 分段机制 187 14.1.4 分页机制 187 14.2 ARM64内存管理 190 14.2.1 页表 192 14.2.2 页表映射 192 14.2.3 页面粒度 194 14.2.4 两套页表 195 14.2.5 页表项描述符 196 14.2.6 页表属 198 14.2.7 连续块表项 201 14.3 硬件管理访问位和脏位 201 14.3.1 访问位的硬件管理机制 201 14.3.2 脏位的硬件管理机制 201 14.4 与地址转换相关的控制寄存器 202 14.4.1 TCR 202 14.4.2 SCTLR 204 14.4.3 TTBR 204 14.5 内存属 204 14.5.1 普通类型内存 204 14.5.2 设备类型内存 204 14.6 案例分析:在BenOS里实现恒等映射 207 14.6.1 页表定义 208 14.6.2 页表数据结构 211 14.6.3 创建页表 211 14.6.4 打开MMU 217 14.6.5 测试MMU 218 14.7 实验 220 14.7.1 实验14-1:建立恒等映射 220 14.7.2 实验14-2:为什么MMU 无法运行 220 14.7.3 实验14-3:实现一个 MMU页表的转能 220 14.7.4 实验14-4:修改页面属导致的系统死机 221 14.7.5 实验14-5:使用汇编语言来建立恒等映射和打开MMU 222 14.7.6 实验14-6:验证LDXR和 STXR指令 222 14.7.7 实验14-7:AT指令 223 第 15章 高速缓存基础知识 224 15.1 为什么需要高速缓存 224 15.2 高速缓存的访问延时 225 15.3 高速缓存的工作原理 227 15.4 高速缓存的映射方式 229 15.4.1 直接映射 229 15.4.2 全相连映射 230 15.4.3 组相连映射 230 15.4.4 组相连的高速缓存的例子 231 15.5 虚拟高速缓存与物理高速缓存 232 15.5.1 物理高速缓存 232 15.5.2 虚拟高速缓存 232 15.5.3 VIPT和PIPT 232 15.6 重名和同名问题 233 15.6.1 重名问题 233 15.6.2 同名问题 234 15.6.3 VIPT产生的重名问题 235 15.7 高速缓存策略 236 15.8 高速缓存的共享属 238 15.8.1 共享属 238 15.8.2 PoU和PoC的区别 239 15.9 高速缓存的维护指令 241 15.10 高速缓存枚举 242 15.11 实验 245 15.11.1 实验15-1:枚举高速缓存 245 15.11.2 实验15-2:清理高速缓存 245 第 16章 缓存一致 246 16.1 为什么需要缓存一致 246 16.2 缓存一致的分类 247 16.2.1 ARM处理器缓存一致发展历程 247 16.2.2 缓存一致分类 248 16.2.3 系统缓存一致问题 249 16.3 缓存一致的解决方案 250 16.3.1 关闭高速缓存 250 16.3.2 软件维护缓存一致 250 16.3.3 硬件维护缓存一致 250 16.4 MESI协议 251 16.4.1 MESI协议简介 252 16.4.2 本地读写线操作 252 16.4.3 MESI状态转换图 253 16.4.4 初始状态为I 253 16.4.5 初始状态为M 256 16.4.6 初始状态为S 257 16.4.7 初始状态为E 258 16.4.8结与案例分析 258 16.4.9 MOESI协议 260 16.5 高速缓存伪共享 261 16.6 CCI和C缓存一致控制器 262 16.6.1 CCI缓存一致控制器 262 16.6.2 C缓存一致控制器 263 16.7 案例分析16-1:伪共享的避免 264 16.8 案例分析16-2:DMA和 高速缓存的一致 265 16.8.1 从内存到设备的 FIFO缓冲区 266 16.8.2 从设备的FIFO缓冲区到 内存 266 16.9 案例分析16-3:自修改代码的 一致 267 16.10 实验 268 16.10.1 实验16-1:高速缓存伪共享 268 16.10.2 实验16-2:使用Perf C2C 发现高速缓存伪共享 268 第 17章 TLB管理 269 17.1 TLB基础知识 270 17.2 TLB重名与同名问题 273 17.2.1 重名问题 273 17.2.2 同名问题 274 17.3 ASID 274 17.4 TLB管理指令 276 17.4.1 TLB维护指令介绍 277 17.4.2 TLB广播 278 17.4.3 TLB维护指令的执行次序 278 17.5 TLB案例分析 278 17.5.1 TLB在Linux内核中的应用 278 17.5.2 ASID在Linux内核中的应用 281 17.5.3 Linux内核中的TLB 维护操作 282 17.5.4 BBM机制 284 第 18章 内存屏障指令 287 18.1 内存屏障指令产生的原因 287 18.1.1 顺序一致内存模型 288 18.1.2 处理器一致内存模型 289 18.1.3 弱一致内存模型 289 18.1.4 ARM64处理器的内存模型 290 18.2 ARM64中的内存屏障指令 290 18.2.1 使用内存屏障指令的场景 290 18.2.2 ARM64里的内存屏障指令 291 18.2.3 DMB指令 291 18.2.4 DSB指令 293 18.2.5 DMB和DSB指令的参数 294 18.2.6 单方向内存屏障原语 294 18.2.7 ISB指令 297 18.2.8 高速缓存维护指令与内存屏障指令 299 18.3 案例分析 300 18.3.1 消息传递问题 301 18.3.2 单方向内存屏障与自旋锁 302 18.3.3 邮箱传递消息 304 18.3.4 与数据高速缓存相关的案例 305 18.3.5 与指令高速缓存相关的案例 307 18.3.6 与TLB相关的案例 309 18.3.7 DMA案例 310 18.3.8 Linux内核中使指令高速缓存失效 310 第 19章 合理使用内存屏障指令 312 19.1 存储缓冲区与写内存屏障指令 313 19.2 无效队列与读内存屏障指令 318 19.3 内存屏障指结 321 19.4 ARM64的内存屏障指令的区别 322 19.5 案例分析:Linux内核中的内存屏障指令 323 19.5.1 第 一次使用内存屏障指令 324 19.5.2 次使用内存屏障指令 326 19.5.3 第三次使用内存屏障指令 329 19.5.4 第四次使用内存屏障指令 330 19.5.5结:内存屏障指令的使用 331 第 20章 原子操作 332 20.1 原子操作介绍 332 20.2 独占内存访问指令 333 20.3 独占内存访问工作原理 334 20.3.1 独占监视器 334 20.3.2 独占监视器与缓存一致 336 20.3.3 独占监视器的粒度 338 20.4 原子内存访问操作指令 338 20.5 比较并交换指令 341 20.6 WFE指令在自旋锁中的应用 342 第 21章 操作系统相关话题 344 21.1 C语言常见陷阱 344 21.1.1 数据模型 344 21.1.2 数据类型转换与整型提升 346 21.1.3 移位操作 348 21.2 函数调用标准 349 21.3 栈布局 351 21.4 创建进程 352 21.4.1 进程控制块 352 21.4.2 0号进程 353 21.4.3 do_fork函数的实现 354 21.4.4 进程上下文切换 355 21.4.5 新进程的第 一次执行 357 21.5 简易进程调度器 357 21.5.1 扩展进程控制块 358 21.5.2 绪队列run_queue 358 21.5.3 调度队列类 358 21.5.4 简易调度器的实现 360 21.5.5 自愿调度 360 21.5.6 抢占调度 362 21.5.7 测例 363 21.6 系统调用 364 21.6.1 系统调用介绍 364 21.6.2 用户态调用SVC指令 364 21.6.3 内核态对系统调用的处理 365 21.6.4 系统调用表 366 21.7 系统启动 367 21.8 实验 368 21.8.1 实验21-1:观察栈布局 368 21.8.2 实验21-2:进程创建 369 21.8.3 实验21-3:进程调度 369 21.8.4 实验21-4:新增一个 malloc()系统调用 369 21.8.5 实验21-5:新增一个clone() 系统调用 370 第 22章 浮点运算与NEON指令 371 22.1 数据模型 371 22.2 浮点运算 373 22.2.1 浮点数 373 22.2.2 浮点控制寄存器与浮点状态寄存器 375 22.2.3 浮点数的条件操作码 377 22.2.4 常用浮点运算指令 377 22.3 NEON指令集 378 22.3.1 SISD和SIMD 378 22.3.2 矢量运算与标量运算 379 22.3.3 加载与存储指令LD1与 ST1 380 22.3.4 加载与存储指令LD2和 ST2 382 22.3.5 加载与存储指令LD3和 ST3 383 22.3.6 加载与存储指令LD4和 ST4 385 22.3.7 加载指令的特殊用法 385 22.3.8 搬移指令 386 22.3.9 反转指令 388 22.3.10 提取指令 389 22.3.11 交错变换指令 390 22.3.12 查表指令 391 22.3.13 乘加指令 391 22.3.14 矢量算术指令 393 22.4 案例分析22-1:RGB24转BGR24 …..393 22.4.1 使用C语言实现RGB24转 BGR24 394 22.4.2 手工编写NEON汇编函数 394 22.4.3 使用NEON内建函数 395 22.4.4 测试 395 22.5 案例分析22-2:4×4矩阵乘法运算 397 22.5.1 使用C语言实现4×4矩阵乘法运算 397 22.5.2 手工编写NEON汇编函数 398 22.5.3 使用NEON内建函数 401 22.5.4 测试 403 22.6 自动矢量优化 404 22.7 实验 406 22.7.1 实验22-1:浮点运算 406 22.7.2 实验22-2:RGB24转BGR32…… 407 22.7.3 实验22-3:8×8矩阵乘法 运算….. 407 第 23章 可伸缩矢量计算与优化 408 23.1 SVE指令介绍 408 23.1.1 SVE寄存器组 408 23.1.2 SVE指令语法 410 23.2 搭建SVE运行和调试环境 410 23.3 SVE特有的编程模式 412 23.3.1 断言指令 412 23.3.2 聚合加载和离散存储 414 23.3.3 基于断言的循环控制 415 23.3.4 基于软件推测的向量分区 421 23.4 SVE与SVE2指令集 422 23.5 案例分析23-1:使用SVE指令优化strcmp()函数 422 23.5.1 使用纯汇编方式 423 23.5.2 测试 425 23.6 案例分析23-2:RGB24转BGR24 ….425 23.6.1 使用纯汇编方式 426 23.6.2 使用内嵌汇编方式 426 23.6.3 测试 427 23.7 案例分析23-3:4×4矩阵乘法运算 428 23.7.1 使用内嵌汇编方式 428 23.7.2 测试 430 23.8 实验 431 23.8.1 实验23-1:RGB24转BGR32 431 23.8.2 实验23-2:8×8矩阵乘法运算 432 23.8.3 实验23-3:使用SVE指令优化strcpy()函数 432

    1.内容系统,突出动手实践 基于树莓派4B开发板,系统介绍ARM64体系结构,内容由浅入深,帮助读者开发运行小型的OS 2.以问题为导向,提率 深入浅出的问题导向式学习方法,各大公司高频面试题,提高读者阅读兴趣 3.趣味案例,常见陷结 基于树莓派4B开发板和QEMU实验平台结了众多一线工程师在实际项目中遇到的陷阱与经验,让你不再害怕踩雷 4.海量资源随书赠送 本书赠送配套VMware开发环境,Linux软,QEMU ARM64实验平台仓库,芯片资料,实验参考代码和配套资料以及配套教学供读者参考学习

    售后保障

    最近浏览

    猜你喜欢

    该商品在当前城市正在进行 促销

    注:参加抢购将不再享受其他优惠活动

    x
    您已成功将商品加入收藏夹

    查看我的收藏夹

    确定

    非常抱歉,您前期未参加预订活动,
    无法支付尾款哦!

    关闭

    抱歉,您暂无任性付资格

    此时为正式期SUPER会员专享抢购期,普通会员暂不可抢购