健哥的技术分享:汇编语言学习方法分享

Linux阅码场 2022-04-22 08:00

阅码场Ftrace公开课火热报名中Ftrace公开课:学优化,学内核(限50人)。课程首发2日报名累计18个,剩余32个名额,先到先得,报名咨询客服(小月微信:linuxer2016)。


这是我3月2日视频分享的文字稿,从汇编语言的本质,学习汇编语言的意义讲到学习方法。


关键词
分享 知识系统 汇编语言 软件 系统软件 芯片 中间件 内核 系统调用 编程模型 汇编 应用层 反汇编 编译器 逻辑运算 操作系统 软硬件接口 体系结构


以下是文字记录

〇、作者简介

在正文之前给先大家做一个简单的自我介绍,自我介绍和后面的内容也是有一定联系的。我大学学的是微电子专业,也就是芯片专业。从2005年读研开始做单片机的开发,后来又去做Linux的系统移植。从那之后基本上一直都是做软件,芯片的东西也有关注,但是没有具体做过,最后一次具体做项目,应该是读研的时候实验室做过一些芯片相关的东西。所以我其实是没有接受过一个特别完整的计算机专业的受训经历的,很多东西都是用到了或者遇到问题的时候再去学习。我在学习的时候特别注重两点,一点是注重知识的系统,另一点是重视回到原始的文档。

一、汇编语言的本质

今天的分享里面也会涉及到知识的系统和原始文档这两点。首先我们为什么要聊要不要学习汇编语言,因为我们不管在学习任何知识的时候,一定都要有两个视角。一个是在这个知识里面,搞清楚这个知识本身是怎么回事。另外一个就是跳出这个知识或者这个技能来看看,从外面往里面看,看看这是什么东西。所以今天的分享,我们先从外往里面先看一下。
首先汇编语言是个什么东西,按照我的理解,汇编语言其实就是计算机软件和硬件的接口。所以这个接口意味着什么呢,意味着我们往下走,可以去了解计算机体系结构,我们往上走,可以去了解操作系统软件。

二、学习汇编语言的意义

我自己一直是在做系统软件的开发,我的工作经验中其实有很多都是操作系统相关的软件。这里面有几个项目都是直接或者间接的用到了汇编语言的技能,给大家先举几个例子。
第一个例子是,大概十年前我在中星微工作的时候,当时负责芯片平台的CPU和环境软件的支持。其中有一项任务是机台测试,机台测试是什么呢,就是我们要去支持在芯片的生产线上去筛选合格和不合格的芯片,这里面需要提供测试用例,有一部分代码必须要使用汇编去写,这个是我第一次手写汇编语言。不仅仅是我在这个经历里面手写了汇编语言,同时为了手写汇编语言还要去了解函数之间是怎么调用的。之前我也知道 ABI 这个概念,ABI 就是 Application Binary lnterface 应用程序的二进制接口。我知道这个概念,但是并不确切知道函数调用之间要符合什么样的规范。我也是在那次的机台测试的时候具体的看了ARM的AAPCS手册,也就是ARM Architecture Procedure Call Standard 的ABI手册。我了解到这个手册之后,我才对这个函数调用之间关系有一个系统的了解。这个也对应到前面我们说的点,就是要注重知识的系统和原始的文档。
第二个例子是,我在SUSE工作的时候遇到的,大家都知道SUSE是第二大的Linux发行版公司,第一大的是RedHat。我当时是做虚拟化,主要负责的是中间件的东西,主要是libvirt和QEMU,也有一点点Xen的工作。这个工作本身它是比较靠上层的,那里面主要的libvirt和QEMU都是用C语言写的,这可以看成是一个C语言的应用开发,这个工作本身几乎是不涉及到汇编语言的。但是那时候发生个事情,就是我们在某一个场景下面,发现那个系统启动有问题。熟悉虚拟化的同学都知道,QEMU里面的系统启动方式跟我们物理机可以一样,也可以不一样。我当时就发现这个问题很奇怪,因为我之前一直做ARM的东西,对x86平台其实是不了解的。此时我有两个选择一个选择,一个是去看x86相关的资料,看一看BIOS这个流程怎么样,启动流程怎么样。但那时候我看了之后发现Google直接得到资料一般都不太具体,它比较抽象,讲的都是大概的流程,没有具体的东西。这个没法支持到我怎么去解决问题,于是那个时候我就尝试着通过汇编语言去看一下BIOS那个代码。我发现,它原来是在某个地方蹦到某个地址,再做跳转,从而完成了从BIOS到下一级BootLoader的启动。
第三个例子就是,我在华为工作的时候做一个跟 ABI相关的事情,我之前也提到过, 就是AARCH64的ILP32的工作,相当于是我在64位的系统里面去用汇编,但是我要支持32位的ELF。这个里面基本上来说因为编译器当时已经差不多做好了,虽然有些bug,但是基本上是没问题的。因为我当时解决的主要是要完善glibc跟内核的这个工作本身几乎不涉及到汇编语言,除了 ld.so和系统调用,例如系统调用中我要考虑怎么去给应用程序给系统将传参。但是在这个项目里面,我发现了解汇编语言还是很有帮助的,为什么呢,因为你去解一些bug的时候,有些地方如果对汇编语言不了解,会很不方便。比如说那时候我们是大端系统,我们首先就要考虑两个问题,就是大小端的转换。我们既要保证这个代码大端是正确的,要保证小端是正确的。第二个事我们要考虑32位和64位的转换,因为我用户端是32位的ELF,进到内核里面是64位的,这两个地方它经常会出一些问题。这个时候除了做代码级的分析之外,另外一个方式就是看反汇编,看看它这个地方32位和64位的关系到底是怎么处理的。
从这三个例子大家可以看到汇编语言其实不仅仅是我们做底层开发,比如开发操作系统,或者说调内核调驱动的时候需要,它其实也是我们去理解CPU的编程模型,去理解系统的一个很好的切入点。所以回到我们最原始的问题,要不要学汇编语言。我自己的体会是,如果工作是涉及到系统软件和中间件,这个是CPU相关的,这个汇编语言是要学习的。如果不是这样,这种工作可能比如说是JAVA 或者别的语言,我觉得相关的像ByteCode的这种相应字节码的一些相关的知识可能也是需要的。

三、如何学习汇编语言

我们前面主要聊了一下要不要学汇编语言,我们下一段主要是分享如何学习汇编语言。那联想一下,前面咱们做内核知识的分享,当时我们分享的时候提到一个点就是软件的分层。大家应该对分层这点都比较熟悉了,我们在学习汇编语言的时候,也可以借助这样一个思想,我先学习什么样的汇编语言呢,先学习哪个层次跟相关的汇编语言呢,显然应用层可能会比较容易一点。
刚开始去看汇编的时候,可以先看一看这个应用层汇编是怎么回事,应用层汇编包括什么内容,我们就可以回到基本的程序设计语言,它基本结构是怎么样的。就是这个顺序判断循环对吧,它这里面就包括了算术运算和逻辑运算,还包括判断和跳转这些基本的指令,有了这些指令之后,我们可以在比如说我们涉及汇编语言和C语言的调用,汇编语言和C++的调用,比如说涉及到的一些 ABI 相关的事情,我们可以有一个汇编的切入点可以去进行查看。同时,如果说crash了或者coredump了或者内核 crash 了,我们借助汇编语言,可以去看一下具体出错那个地方,因为反汇编得到的C语言的行号可能没有那么准确。
那除此之外,我们在了解了算数运算逻辑运算这些基本的汇编之后,还可以再去深入的学习。在这个地方我们先停留一下,我们怎么去学呢,比较直接的办法当然是我们找一些资料去学习,这肯定是没问题的。还有什么办法呢,比如我去看体系架构的手册,比如看x86、ARM、RISC-V的架构手册,我们去看这些手册里面具体是怎么写的。我觉得这是一个最终的目标,如果最终我们能够基于这些手册去解决我们汇编语言相关的问题,那么这个汇编语言的学习就比较到位了,可以说是已经到了一个可以自己进行自我迭代的一个程度了。问题在于我们怎么能够进入到这样一个状态,直接去看这些架构手册的话还是非常有挑战性的。
那么我们学习汇编语言的方式应该是什么呢,这个方式就可以是,我们自己写段代码,不要开启编译器的-O3等各种优化选项,然后看看反汇编是什么样子的。这样我们就能对基本的汇编语言有一个基本的了解。当然在实际工作中,我们可能会开启 -O3 -Os这些编译选项,这些都没关系的。我们再去对比它开与不开有什么区别,汇编指令有哪些不同,这样我们就有了第一手的素材,对汇编语言就有了一个基本的了解。同时在这个层次上可能还会出现一个什么情况,我们可能有时候会看到一些内嵌汇编,那看到内嵌汇编,比如说是GCC的内嵌汇编,根据我们前面说的我的学习方法,我们还要回到原始的文档。
那么GCC的汇编语言,就要去看GCC的手册,GCC关于内嵌汇编有很详细的说明,详细的说明里面我们能不能根据详细的说明去理解,我该怎么去写这些GCC的内嵌汇编的。同时这个地方涉及到一些ABI的知识,就是什么情况下我需要用那些extra的一些flag(参见参考资料1)。那么这个地方你可以看到它其实又是一个软硬件的一个接口,我们其实是在学习汇编语言,其实看的是我们对于系统软件的了解,对于 CPU 架构的了解。
那么我们对于简单的汇编如算术逻辑运算判断跳转有了一个了解之后,我们再往下走是什么呢。我们会看到一些比如说操作内核,它用的汇编跟应用的汇编有什么区别。区别就是操作系统内核是一个privilege,特权级别,这个特权级别它就会对应到一些特权相关的指令。比如说如何进入和退出一个特权级别,比如说如何去操作一些 CPU 的控制寄存器。这些控制寄存器可能涉及到操作系统的一些能力,比如说中断使能、系统调用的路由、中断路由这些事情。在这个地方其实我们有可以看到,汇编语言和CPU架构其实是高度相关的。也就是说我们可以在学习某个CPU架构的时候,我们去对照汇编去看一些操作系统比如Linux、RTT,它是怎么去写这个汇编语言的。同时我们也可以基于某一次对操作系统比如Linux的一个调试,我们基于调试中我们看到一些我们之前没有见过的汇编的一些语言,再切入回来,再去看一看它跟CPU架构有时么关系,哪些是跟CPU架构相关的。
除了我们刚刚说的系统分层这块之外,系统分层里面还有什么内容呢。比如说Memory模型,像ARM和RISC-V,它都是统一寻址的,如果是x86,它其实还有传统的方式,还包括一个IO寻址的方式。这种东西它在汇编语言里面也有会有所区别,同时在Memory模型里面还有一块页表处理。页表处理里面页表基址在什么地方,有几个页表基址,这些又都涉及到汇编语言去访问特殊功能的寄存器。
那通过这样一个学习呢,我们基本来说对于汇编语言就有了一个整体的了解了,不管是应用挂了还是操作系统内核挂了我们都可以去调试。那这个是不是就学完了呢,还没有,为什么呢,因为还有一个很重要的概念就是pseudo assembly,就是伪汇编。伪汇编这个东西,我们平时用得非常广泛。大家平时不知道有没有遇到过这样的问题,我看到一段代码,但是我去搜手册就是没搜到这个汇编在哪,但是它明明是汇编器能编译过的,还是能用的一个商业/开源软件。它为什么就不知道在哪了,那这个就是伪汇编,对吧。其实它并不单独对应某一条机器指令,它其实是某个汇编指令的一个变化,或者是多条指令的集合。
那伪汇编其实是跟架构相关的,不同的CPU架构它会不一样。比如说RISC-V,它其实在RISC-V spec里面是有写到的。它也有专门的ASM手册,里面也会单独写都有哪些伪汇编指令。了解伪汇编指令,其实是很重要的,就是看我们的汇编语言学习到底是不是实操,到底我只是知道纸面上知道这些汇编语言,还是说我真正在工程里面调过汇编语言。因为工程里面它有很多都是伪汇编了,如果我没有看位汇编的话,那么可能在实际工程中看别人写的代码就会比较费劲。
OK, 刚刚说到基本的算术逻辑运算判断跳转,还有特权指令,Memory模型、伪汇编,除此之外汇编语言里面还有什么内容呢?其实还有一些内容,比如说像x86的3DNow  MMX这种多媒体指令。还有ARM的NEON指令,VFP的这种浮点指令。这些指令它也会对应的汇编。这些汇编和前面的逻辑差不多,我们也是要看基本的应用是怎么用的,然后再看它还要考虑一点,整数跟这种浮点之间它相互调用是怎么操作的,这个地方我就不展开讲了。

四、推荐的书籍与文档

所以可以看到,其实我们在整个学习过程中,我觉得比较重要的一点就是注重回到原始文档。原始文档有什么,比如说 CPU的架构手册,比如操作系统的代码,比如操作系统的一些重要的书籍。我是建议大家日常至少应该有两本,一本是讲 CPU讲计算机组成原理的书,比如说《计算机组成原理与设计软硬件接口》那本书,然后还有一块应该就是操作系统的书了,比如说我最近正在看陈海波老师写的《现代操作系统》。我觉得经典的书都可以,也不用说去纠结到底看哪一本。我的建议是我们对照CPU和操作系统的两本书去看,我们会发现有些内容CPU的书里面讲的比较多,有些内容操作系统的书里面讲得比较多一点。
我们要不断的注重回到原始的文档,除了计算机体系结构和操作系统的书之外呢,平时可能还需要看的就是这个ABI相关的这些手册。大家可以趁这个机会去看一看,大家自己平时用的常用的CPU就是 x86、ARM、RISC-V,那这里面哪些资料你可以再去看一看。大家可以先把自己手头的资料给它补齐,补齐之后呢我们基于问题再去对应相应的资料,最终目标应该是能够看到原始的文档去解决问题。

五、总结

这个就是我今天的分享。总结一下,今天我是从自我介绍开始的。因为我是转专业的,所以我会比较重视知识的系统和原始的文档。今天我们是从汇编语言是软硬件接口开始分享。我首先举了三个我自己的项目经历,有些是明显要写汇编的,有些是看起来跟汇编语言无关,但是由于为了解决问题去看了汇编语言。还有一些,是跟体系结构操作系统有点关系,会比较多地涉及到通过汇编语言做调试。这也就是说,系统软件包括中间件这些软件可能我们在调试的时候了解汇编语言,对我们的工作可能会或多或少的有一些帮助。第二部分我分享的是如何学习汇编语言。我们站在分层的角度先去学习应用层次的汇编语言。然后再往深了一层去看特权级别的汇编语言有什么不一样,这涉及到一些特权指令,涉及到Memory模型的一些内容,最后我们说伪汇编和浮点指令这些内容。
感谢程磊童鞋帮忙整理文字稿。
我是张健,前华为架构师,前创业公司技术合伙人,目前自由职业。同时我是两个孩子的爸爸。在职业发展,工作和生活如何平衡方面有很多第一手经验。欢迎大家与我探讨。
参考资料
  1. https://gcc.gnu.org/onlinedocs/gcc/Extended-Asm.html


往期精华文章:【精华】Linux阅码场原创精华文章汇总


阅码场付费会员专业交流群

会员招募:各专业群会员费为88元/季度,权益包含群内提问,线下活动8折,全年不定期群技术分享(普通用户直播免费,分享后每次点播价为19元/次),有意加入请私信客服小月(小月微信号:linuxer2016)


专业群介绍:

彭伟林-阅码场内核性能与稳定性
本群定位内核性能与稳定性技术交流,覆盖云/网/车/机/芯领域资深内核专家,由阅码场资深讲师彭伟林主持。


甄建勇-Perf Monitor&Perf Counter

本群定位Perf、cache和CPU架构技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师甄建勇主持。


邓世强-Xenomai与实时优化

本群定位Xenomai与实时优化技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师邓世强和彭伟林共同主持。


周贺贺-Tee和ARM架构

本群定位Tee和ARM架构技术交流,覆盖云/网/车/机/芯领域资深用户,由阅码场资深讲师周贺贺主持。




Linux阅码场 专业的Linux技术社区和Linux操作系统学习平台,内容涉及Linux内核,Linux内存管理,Linux进程管理,Linux文件系统和IO,Linux性能调优,Linux设备驱动以及Linux虚拟化和云计算等各方各面.
评论 (0)
  • 一、系统概述MYD-LD25X搭载的Debian系统包含以太网、WIFI/BT、USB、RS485、RS232、CAN、AUDIO、HDMI显示和摄像头等功能,同时也集成了XFCE轻量化桌面、VNC远程操控、SWITCH网络交换和TSN时间敏感网络功能,为工业设备赋予“超强算力+实时响应+极简运维”的体验!类别名称描述源码TF-AArm Trusted Firmware 2.8OP-TEEOP-TEE 3.19BootloaderU-boot 2022.10KernelLinux Ke
    米尔电子嵌入式 2025-03-07 14:08 223浏览
  • Sub-GHz,即工作频段低于1GHz的无线通信技术,常见频段有315MHz、433MHz、868MHz与915MHz等。其可借助无线电波在自由空间传播的特性,把数据调制到射频载波上进行传输,达成物联网设备间的无线通信,是物联网设备实现高效、稳定、无缝交互的“通信基石”。典型射频信号(无线电波)收发电路简示在工业自动化、智慧城市、智慧农业与智能家居等物联网领域中,LoRa、Wi-SUN、Z-Wave、Sigfox等工业级通信协议大多运行在Sub-GHz频段。而正是通过Sub-GHz射频技术,传感
    华普微HOPERF 2025-03-07 11:39 144浏览
  • ​CS6212是一款可分别用于USB Type-C主机/显示端口源应用的带重定时的有源开关。这设备符合USB 3.2标准版本1.0和USB Type-C标准上的VESA DisplayPort Alt模式 1.0版,支持通过GPIO或12C进行灵活的模式切换。此设备支持USB 3.2第2x1代 运行速度高达10Gbps,DisplayPort 1.4运行速度高达HBR3 8.1Gbps。CS6212管脚分布及功能定义:CS6212支持重定时器训练,并支持USB 3.2标准中定义的状态状态机(RT
    QQ1540182856 2025-03-07 10:09 150浏览
  • 深圳触觉智能RK3506开发板现已上市,开启预售!搭载瑞芯微RK3506B/J超低功耗工业处理器(1.5GHz三核A7+M0,主频1.5GHz);支持1280×1280显示、双百兆网口、星闪无线三模,板载高达2路CAN FD与5路串口。RK3506适用场景简介工业控制‌:RK3506适用于工业控制、工业通信、人机交互等应用场景。其多核异构架构(3xCortex-A7+Cortex-M0)和外设接口丰富,支持Buildroot、Yocto系统,适合轻量级HMI应用‌。‌工业通信‌:RK3506均支
    Industio_触觉智能 2025-03-07 10:04 119浏览
  • 近年来,越来越多的企业在5S管理的基础上,开始追求6S、7S甚至8S管理,仿佛S越多,管理就越先进,企业就越优秀。于是,6S增加了“安全”,7S又加上了“节约”,8S甚至引入了“学习”……看似更加全面,实则很多企业只是机械地增加S,却忽略了管理的核心目标:提升效率、降低浪费、优化工作环境。优思学院认为,5S本身已经是一套成熟的精益管理工具,它的核心理念不仅简单高效,而且易于实施和推广。如果企业只是为了赶时髦,盲目增加S,而没有真正理解5S的本质,那么这些额外的“S”很可能会变成管理上的负担,而不
    优思学院 2025-03-07 12:43 165浏览
  • 服务器应用环境与客户需求PCIe 5.0高速接口技术的成熟驱动着生成式AI与高效能运算等相关应用蓬勃发展。在随着企业对服务器性能的要求日益严苛,服务器更新换代的周期也持续加快。在此背景下,白牌与DIY(Do It Yourself)服务器市场迎来了新的发展契机,但同时也面临着更趋复杂的技术挑战。传统上,白牌与DIY服务器以其高度客制化与成本效益优势受到市场青睐。然而,随着PCIe 5.0等高速技术的导入,服务器系统的复杂度大幅提升,对组装技术与组件兼容性也就提出更高的要求。举个简单的例子来说,P
    百佳泰测试实验室 2025-03-06 17:00 158浏览
  • ASL6328芯片支持高达 6.0 Gbps 运行速率的交流和直流耦合输入T-MDS 信号,具备可编程均衡和抖动清理功能。ASL6328 是一款单端口 HDMI/DVI 电平转换 / 中继器,具有重新定时功能。它包含 TypeC双模式 DP 线缆适配器寄存器,可用于识别线缆适配器的性能。抖动清理 PLL(锁相环)能够消除输入抖动,并完全重置系统抖动容限,因此能更好地满足更高数据速率下 HDMI 抖动合规性要求。设备的运行和配置可通过引脚设置或 I2C 总线实现。自动断电和静噪功能提供了灵活的电
    QQ1540182856 2025-03-06 14:26 131浏览
  • 多人同时共享相同无线网络,以下场景是否是您熟悉的日常?姐姐:「妈~我在房间在线上课,影音一直断断续续的怎么上课啊!」奶奶:「媳妇啊~我在在线追剧,影片一直卡卡的,实在让人生气!」除此之外,同时间有老公在跟客户开在线会议,还有弟弟在玩在线游戏,而妈妈自己其实也在客厅追剧,同时间加总起来,共有五个人同时使用这个网络!我们不论是在家里、咖啡厅、餐厅、商场或是公司,都会面临到周遭充斥着非常多的无线路由器(AP),若同时间每位使用者透过手机、平板或是笔电连接到相同的一个网络,可想而知网络上的壅塞及相互干扰
    百佳泰测试实验室 2025-03-06 16:50 153浏览
  •        深夜的公园里,当路灯熄灭后,传统监控摄像头只能拍出模糊的黑白画面,仿佛老式胶片电影里的场景。而搭载为旌瑶光ISP的摄像头,却能像猫科动物一样,在几乎全黑的环境中捕捉到行人衣服的颜色、树叶的纹理,甚至快速跑动的宠物狗毛发细节。这种从“黑白默片”到“全彩4K电影”的跨越,背后是为旌瑶光ISP对传统红外补光技术的颠覆性创新。一、传统方案之困:被红外光“绑架”的夜视世界        传统安防摄像头依赖红外
    中科领创 2025-03-07 16:50 276浏览
  • 在企业管理和职场环境中,权力是一个常被提及却又让人感到微妙的话题。有人觉得它充满吸引力,有人却对它避之不及。然而,不管你对权力的态度如何,理解它、掌握它,甚至善用它,都是职场成功的重要一环。今天,我们就来深入探讨权力的本质,特别是个人权力和社会权力的区别,以及如何在职场中逐步建立属于自己的影响力。权力的两种面貌:你掌控自己,还是掌控他人?说到权力,首先要区分它的两种类型。个人权力是你对自己生活的掌控感。比如,你能自由决定自己的职业方向,不用总是请示他人。这种权力让人感到踏实和满足,是我们在生活中
    优思学院 2025-03-07 15:56 172浏览
  • 文/Leon编辑/cc孙聪颖2025年全国两会进行时,作为“十四五”规划收官之年,本届两会释放出坚定目标、稳中求进、以进促稳等信号。其中,企业家们的建议备受关注,关系到民营经济在2025年的走向。作为国内科技制造业的“老兵”,全国人大代表、TCL集团创始人及董事长李东生在本届两会中提出三份代表建议,包括《关于优化中国科技制造业融资环境的建议》、《关于加强AI深度伪造欺诈管理的建议》和《关于降低灵活就业人员社会保险参保门槛的建议》,表现出对科技制造、AI发展和劳动者保障方面的关注。会后,李东生接受
    华尔街科技眼 2025-03-06 19:41 123浏览
  • 深圳触觉智能SOM3506核心板现已上市,搭载瑞芯微RK3506B/J超低功耗处理器(1.5GHz三核A7+M0),低功耗满载仅0.7W,支持40℃~85℃工作环境,即日起宽温级59元/工业级68元,特价开售!芯片介绍RK3506是瑞芯微Rockchip在2024年第四季度全新推出的Arm嵌入式芯片平台,三核Cortex-A7+单核Cortex-M0多核异构设计,CPU频率达1.5Ghz, M0 MCU为200Mhz。RK3506适用场景简介工业控制‌:RK3506适用于工业控制、工业通信、人机
    Industio_触觉智能 2025-03-07 10:03 139浏览
我要评论
0
0
点击右上角,分享到朋友圈 我知道啦
请使用浏览器分享功能 我知道啦