汇编语言知多少(一): 概论

编程语言的发展

  • 机器语言: 由 0 和 1 组成.
  • 汇编语言(Assembly Language): 用符号代替了 0 和 1, 比机器语言更加便于阅读和记忆.
  • 高级语言: C\C++\Java\Swift等, 更加接近于人类自然语言.

    来源维基百科-汇编语言

操作:
将寄存器 BX 的内容送到寄存器 AX.

机器语言: 1000100111011000
汇编语言: mov ax, bx
高级语言: ax = bx
  • 汇编语言与机器语言一一对应,每一条机器指令都有与之对应的汇编指令
  • 汇编语言可以通过编译得到机器语言,机器语言可以通过反汇编得到汇编语言
  • 高级语言可以通过编译得到汇编语言\机器语言,但汇编语言\机器语言几乎不可能还原成高级语言

汇编语言的特点

  • 可以直接访问, 控制各种硬件设备, 比如存储器, CPU等, 能最大限度发挥硬件的功能.
  • 汇编指令是机器指令的助记符, 和机器指令一一对应, 每一种CPU都有自己的机器指令集 \ 汇编指令集, 所以汇编语言不具备可移植性.
  • 不区分大小写, mov 和 MOV 是一样的.

采用高级语言C++和汇编语言编写同一个功能, 将 a + b 的结果赋值给 c, 然后打印 c 的结果.

语言 源文件大小 目标文件大小 可执行文件大小
汇编语言 近400字节 近200字节 近600字节
C++ 近150字节 近550字节 近9000字节

由于C++会链接很多底层库, 所以可执行文件会大这么多.

汇编语言的分类

要弄清楚这个, 我们先讲一下微处理器.

微处理器(Microprocessor)是可编程特殊集成电路, 其所有组件小型化至一块或数块集成电路内, 可在其一端或多端接受编码指令,执行此指令并输出描述其状态的信号. 又称半导体中央处理器,是微型计算机的一个主要部件.

  • 在具有微程序控制的指令集的微型计算机中, 微处理器不仅具有算术逻辑单元和控制逻辑单元, 还有控制存储单元.
    • 用于处理通用资料,叫作 CPU (Central Processing Unit), 中央处理器.
    • 用于图像资料处理, 叫作 GPU (Graphics Processing Unit), 图形处理器.
    • 用于音讯资料处理, 叫作 APU (Audio Processing Unit), 音讯处理器.
    • 其他
  • 微处理器工作原理
    • 通过设计好的指令集, 来输入对应的指令, 控制处理器实现相应的功能.
    • 所以指令集决定了处理器的架构, 由于不同的公司设计不一样的指令集, 导致对应的硬件电路都可能不一样.
    • 汇编语言是用助记符来描述指令集. 便于人类编码.
时间 事件
1971年 Intel公司发布世界第一款4位微处理器 4004
1972年 Intel公司发布世界第一款8位微处理器 8008
1978年 Intel公司发布16位微处理器 8086(是x86系列第一款)
1982年 AT&T贝尔实验室设计的世界第一款32位微处理器BELLMAC-32A投产
1990年 用RISC技术(精简指令集)设计全球第一款64位微处理器 R4000

那么汇编语言怎么分类呢?

  • 按照指令集架构分类:

    • 8086汇编(16bit), x86系列第一款. 我们学习的就是这一种,
    • x86汇编(32bit), 这种架构常被称为i386, x86, 它是 Intel 设计的
    • x86汇编(64bit), 这种架构常被称为 AMD64, Intel64, x86-64, x64, 它是 AMD 设计的, 是x86架构的64位扩展, 后来公开, 也被Intel所采用, 故现在也称为 Intel64.
    • ARM汇编, ARM处理器由于高性能, 低耗电, 常用于嵌入式, 移动设备.
    • 其他
  • 按照汇编格式分类: 这几种基本上是符号系统的区别

    • Intel 格式
    • AT&T 格式
    • ARM 格式
    • 其他

指的一提的是

  • x86 汇编指令的风格是 Intel 汇编, 被 Microsoft Windows, Visual C++ 采用.
  • x64 汇编指令的风格是 AT&T 汇编, 被 GNU, Gas 采用(Gas 也可使用Intel汇编).
  • ARM 汇编指令的风格是 ARM 汇编.被 Apple 采用. 应用于 iPhone 真机.
Intel 处理器
ARM 处理器

汇编语言的用途

  • 编写驱动程序, 操作系统(比如Linux内核的某些关键部分).
  • 对性能要求极高的程序或者代码片段,可与高级语言混合使用(内联汇编).
  • 软件安全
    • 病毒分析与防治.
    • 逆向\加壳\脱壳\破解\外挂\免杀\加密解密\漏洞\黑客.
  • 是理解整个计算机系统的最佳起点和最有效途径, 为编写高效代码打下基础.

了解 CPU 等硬件结构.

软件\程序执行的过程

image.png

每一个CPU芯片都有许多管脚, 这些管脚和总线(Bus)相连, CPU 通过总线跟外部器件交互.

8086芯片
  • 地址总线(Address Bus): 它的宽度决定了 CPU 的寻址能力
  • 数据总线(Data Bus): 它的宽度决定了 CPU 的单次数据传送量, 也就是数据传输速度.
  • 控制总线(Control Bus): 它的宽度决定了 CPU 对其他器件的控制能力, 能有多少控制.
  • CPU 通过控制总线传输读命令, 通过地址总线指定是内存中的3号单元, 通过数据总线传输数据 0000 1000 (08)
  • 这里面的 0, 1 是指的是线路中的 高电平, 低电平. 线路越宽, 能传输的数据越多

数据总线

8088的数据总线宽度是 8 根, 8086 的数据总线宽度是 16根, 那么分别向内存中写入 89D8H.

练习:

  • 1 个 CPU 的寻址能力是 8 KB, 那么他的地址总线的宽度数: 13, 因为 8KB = 2^{13}
  • 8086, 8088, 80286, 80386 的地址总线宽度为16根, 20根, 24根, 32根, 那么他们的寻址能力分别是 64KB, 1MB, 16MB, 4GB, 因为
    • 2^{10} = 1KB, 2^{16} = 64 KB
    • 2^{20} = 1024KB = 1 MB,
    • 2^{24} = 16 * 1024KB = 16 MB,
    • 2^{32} = 2^{12} * 1MB = 4 * 1024 * 1MB = 4GB
  • 8086, 8088, 8086, 80286, 80386 的数据总线宽度为8根, 8根, 16根, 16根, 32根, 那么他们一次可以传送的数据是: 1B, 1B, 2B, 2B, 4B,
    • 因为传输 1Byte 的数据实际是8bit .
  • 从内存中读取 1024 字节的数据, 8086至少读 512 次,
    • 因为 1024B = 2^{10} B, 8086 的传输速度是 2B / 次, 所以需要 512 次.

这里再啰嗦一遍, 1 字节 = 8 位, 1 Byte = 8 bit, 我们常说的 64 位操作系统, 指的是CPU 每次能处理 64 bit 的数据.

内存

各类存储器的逻辑连接与物理连接对应图.


image.png

所有的内存单元都有唯一的地址, 叫作物理地址, 内存地址空间的大小受 CPU 地址总线宽度的限制.

8086的地址地址总线宽度为20, 可以定位 2^{20} 个不同的内存单元, ( 内存地址范围为0x00000 ~ 0xFFFFF), 所以8086的内存空间大小为 1 MB.
注: 2^{20} = 1048576 , 0xFFFFF => 1048575

  • 0x00000 ~ 0x9FFFF: 主存储器, 可读可写.
  • 0xA0000 ~ 0xBFFFF: 向显存中写入数据, 这些数据会被显卡输出到显示器, 可读可写.
  • 0xC0000 ~ 0xFFFFF: 存储各种硬件\系统信息, 只读.


    image.png

8086的寻址方式

  • CPU访问内存单元时, 要给出内存单元地址.
  • 8086有 20位 的地址总线, 可以传送 20 位的地址, 1M 的寻址能力.
  • 但它又是 16位 结构的CPU, 它内部能够一次性处理, 传输, 暂时存储的地址为 16位. 如果将地址从内部简单发出, 那么它只能送出 16位 的地址, 表现出来的寻址能力只有 64KB
  • 所以8086采用了一种在内部使用 2个16位 地址合成的方式来生成 1个20位 的物理地址.

地址加法器采用 物理地址 = 段地址 x 16 + 偏移地址 的方式合成物理地址.
比如 8086CPU 要访问地址为 123C8H 的内存单元

我们又能发现, 8086CPU的要访问的同一个 物理地址 可以由不同的 段地址偏移地址 组成.

内存的分段管理

  • 8086采用 起始地址(段地址x16) + 偏移地址 = 物理地址 的方式来给出物理地址.
  • 为了开发方便, 我们采用分段的方式来管理内存.
    • 比如地址 10000H ~ 100FFH 组成一段, 那么起始地址为 10000H, 段地址为 1000H, 大小为 100H.

如果给定一个段地址, 仅通过变化偏移地址来进行寻址, 最多可定位多少个内存单元?
偏移地址为 16 位, 变化范围为 0 ~ FFFFH, 仅用偏移地址来寻址, 最多可寻64KB个内存单元(2^{16} = 64KB) , 若给定段地址为 1000H, 用偏移地址寻址, CPU的寻址范围为 10000H ~ 1FFFFH.

在 8086PC机中, 存储单元的地址用段地址和偏移地址来描述, 
比如数据在 21F60H 内存单元中, 对于 8086PC机来说, 数据存在内存2000: 1F60单元中, 
或者数据存在 2000H段 中的 1F60H 单元中.

CPU的典型构成

不同的 CPU, 寄存器的个数, 结构是不同的, 8086 有 14 个寄存器, 都是16位 寄存器, 每个可以存放 2个 字节.


寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和地址.

通用寄存器

  • AX, BX, CX, DX这四个寄存器通常用来存放一般的数据, 也被称为是 通用寄存器, 通常, CPU会先将内存中的数据存储到通用寄存器中, 然后再对通用寄存器中的数据进行运算.
  • 假设内存中有一块内存空间的值是 3, 现在想把它的值加 1 , 并将结果存储在新的内存空间中.
    • mov ax, srcMemory: CPU 先将原来内存空间的值存在寄存器中
    • add ax, 1 : 让寄存器ax与 1 相加.
    • mov desMemory, ax : 将值赋给新的内存空间.
  • AX, BX, CX, DX这四个通用寄存器是16位的, 里面AH, AL 分别代表高位寄存器, 和低位寄存器, 其他同理.

在汇编的数据存储中

  • 字节: byte, 1 个字节由8 bit组成
  • 字: word, 1个字由2个字节组成

上面展示的数据 20000 (4E20H), 字: 010011100 0100000B, 左边是 高八位, 右边是低八位.

段寄存器
8086 存在4个段寄存器, 当 CPU 需要访问内存时, 由这4个提供段寄存器提供内存单元的 段地址.

  • CS (Code Segmnet): 代码段寄存器
  • DS (Data Segmnet): 数据段寄存器
  • SS (Stack Segmnet): 堆栈段寄存器
  • ES (Extra Segmnet): 附加段寄存器
  1. 8086CPU 当前状态: CS 中的内容为 2000H, IP 中的内容是 0000H, CS 为代码段寄存器, IP (Instruction Pointer Segment)为指令指针寄存器, 他们指示了 CPU 当前要读取指令的地址.
  2. 内存 20000H ~ 20009H 单元存放着可执行的机器码.
  • 地址: 20000H ~ 20002H, 内容: B8 23 01, 长度 3 Byte, 汇编指令: mov ax, 0123H
  • 地址: 20003H ~ 20005H, 内容: BB 03 00, 长度 3 Byte, 汇编指令: mov bx, 0003H
  • 地址: 20006H ~ 20007H, 内容: 89 D8, 长度 2 Byte, 汇编指令: mov ax, bx
  • 地址: 20008H ~ 20009H, 内容: 01 D8, 长度 2 Byte, 汇编指令: mov ax, bx

下面将详细就介绍 CPU 如何处理汇编指令.

  1. CS, IP 中的内容送到 地址加法器 中, 物理地址 = 段地址 x 16 + 偏移地址, 输出 20000H
  2. 地址加法器 将物理地址送入到 输入输出控制电路.
  3. 输入输出控制电路 将物理地址 20000H 输入到 地址总线 开始寻址.
  4. 从内存 20000H 单元开始存放的机器指令 B8 23 01 通过 数据总线 被送入到 CPU.
  5. 输入输出控制电路 将机器指令 B8 23 01 送入 指令缓冲器.
    • 此时 IP 中的值自动增加, 以便CPU 可以读取下一条指令
    • 因为当前读入的指令 B8 23 01 长度为 3 个字节, 所以 IP 中的值加 3, 此时CS: IP执行内存单元 2000: 0003
  6. 执行控制器 执行指令 B8 23 01, 即 mov ax, 0123H, 此时 AX 中的内容为 0123H.
  7. CPU 从内存 20003H 处读取指令 BB 03 00, 送入 指令缓冲器, 此时 IP 再次加 3.
  8. 执行指令 BB 03 00 即 mov bx, 0003H.
  9. CPU 从内存 20006H 处读取指令 89 D8, 输入指令缓冲器. 此时 IP 值加 2.
  10. 执行指令 89 D8, 即 mov ax, bx, AX 中的内容变为 0003H.
  11. CPu 从内存 20008H 读取指令 01 D8 入指令缓冲器. IP 的值加 2 .
  12. 执行指令 01 D8, 即 add ax, bx, AX 中的内容变为 0006H.

上面这个过程可以简述为

  1. 从 CS: IP 指向的内存单元读取指令, 读取的指令进入指令缓冲器.
  2. IP = IP + 所读取指令的长度, 从而指向下一个指令的.
  3. 执行指令, 重复步骤1, 重复这个过程.

指令和数据

看完上面这个过程, 我们会发现 指令和 数据都是二进制信息,
比如 内存中二进制信息 10001001 11011000, 既可当做数据 89D8H , 也可当做指令 mov ax, bx

那么 CPU 怎么区分两者呢

  • CPU 将 CS: IP 指向的内存单元的全部内容看做指令. 指令里面可能包含数据.
  • 如果内存中的某段内容曾被CPU执行过,那么它所在的内存单元必然被CS:IP指向过

处理器架构、指令集和汇编语言,三者有何关系
维基百科-汇编语言
维基百科-X86
维基百科-ARM架构
维基百科-微处理器
维基百科-寄存器

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容

  • 8086汇编 本笔记是笔者观看小甲鱼老师(鱼C论坛)《零基础入门学习汇编语言》系列视频的笔记,在此感谢他和像他一样...
    Gibbs基阅读 37,077评论 8 114
  • 编程语言的发展 机器语言由0和1组成 汇编语言(Assembly Language)用符号代替了0和1,比机器语言...
    阿凡提说AI阅读 3,945评论 0 15
  • 越底层越单纯!真正的程序员都需要了解的一门非常重要的语言,汇编! 机器语言 我们所写的语言最终安装在机器上的是什么...
    瑞阳gg阅读 576评论 0 0
  • 汇编总结 汇编的发展史 机械语言 由0和1组成的机器指令(如:0101 0001 1101 0110) 汇编语言(...
    iChuck阅读 1,297评论 1 8
  • 王爽汇编全书知识点大纲 第一章 基础知识 机器语言 汇编语言的产生 汇编语言的组成 存储器 cpu对存储器的读写 ...
    2c3ba901516f阅读 2,401评论 0 1