跳转至

Part 1. 基础知识⚓︎

2057 个字 4 行代码 预计阅读时间 10 分钟

背景知识⚓︎

汇编语言基础⚓︎

  • 汇编语言是对机器语言的符号化
  • 汇编语言与 CPU 和操作系统密切相关

    • 现代操作系统对操作系统和用户程序的权限做了严格区分,因此无法执行特权命令
    • DOS 系统没有这种限制,故课上介绍的是古老的 DOS 系统下的 80x86 汇编语言
  • 特点:

    • 控制强:
      • 最接近机器语言,因此更容易控制硬件
      • 汇编语言的“材料”——指令与中断调用相对高级语言的“材料”(语句与函数调用)小,因此用汇编语言可以写出高级语言无法实现的程序
    • 代码短:用汇编语言写的程序经编译后生成的可执行代码比高级语言的要短
    • 速度快
  • 组成部分:

    • 汇编指令:机器码的助记符,可以被计算机执行,是汇编语言的核心
    • 伪指令:没有对应的机器码,由编译器识别并翻译,计算机并不执行
    • 其他符号

硬件基础知识⚓︎

这里涉及到的硬件知识只是抽象层面的,并不会涉及到电路连接、逻辑门之类的。

  • 内存 / 存储器

    • 存储了 CPU 可以直接使用的信息
    • 在内存中数据和指令没有任何区别,都是二进制信息
    • 1 个内存单元对应 1 字节的信息,以及 1 个地址
    • 各类存储器芯片:
      • 随机访问存储器 (RAM):存放 CPU 使用的绝大部分程序和数据
      • 装有 BIOS(基本输入输出系统)的只读存储器 (ROM)
        • BIOS 是主板和各类接口卡厂商提供的软件系统,通过 BIOS 可对硬件设备进行最基本的输入输出
        • 主板和接口卡的 ROM 用于存储相应的 BIOS
      • 接口卡上的 RAM:某些接口卡需要对大批量输入 / 输出数据进行暂时存储,比如显卡的 RAM(称为显存)
    • 内存地址空间:一种逻辑存储器(与计组提到的虚拟内存类似)

      • CPU 将系统中各类(物理)存储器看作一个逻辑存储器
      • 每个物理存储器在逻辑存储器中占有一个地址段,称为段地址空间
      • 8086 系统的内存地址空间分配情况(地址范围
        • 主存储器(包括用户数据和中断向量表)地址空间:[0000:0000, 9000:FFFF]
        • 显存地址空间:[A000:0000, B000:FFFF]
          • 图形模式:[A000:0000, A000:FFFF]
          • 文本模式:[B800:0000, B800:7FFF]
        • 各类 ROM 地址空间:[C000:0000, F000:FFFF]
      显卡(显存)地址映射

      显卡地址映射分为文本模式(text mode) 图形模式(graphics mode),具体来说:

      \(80 \times 25\)(每行 80 个字符,每列 25 个字符)文本模式的屏幕坐标系统如图所示:

      • 每两个内存单元(2 字节)决定屏幕上的一个字符

        • 前一个内存单元(1 字节)表示字符的 ASCII 码值
        • 后一个内存单元(1 字节)表示字符的颜色,每个位的意义如下所示:

          7: 闪烁
          6: 红
          5: 蓝
          4: 绿
          
          3: 高亮
          2: 红
          1: 绿
          0: 蓝
          
          • 4 位表示背景色
          • 4 位表示前景色
      • 屏幕坐标 (x, y) 对应的显卡偏移地址text_mode_offset的计算公式为:

        text_mode_offset = (y * 80 + x) * 2
        
      • 虽然这是一个二维平面,但是在内存中所有的数据都是连续的(图中的 79x2 80x2 表示的是十进制的偏移地址,为了方便就这样写了)

      例子

      ds=0B800h

      mov byte ptr ds:[0], 'A'
      mov byte ptr ds:[1], 74h
      mov byte ptr ds:[2], 'B'
      mov byte ptr ds:[3], 72h
      

      结果是:

      \(320 \times 200\) 图形模式的屏幕坐标系统如图所示:

      • 1 个内存单元(1 字节)决定屏幕上的一个点,其值代表该点的颜色(256 种)
      • 屏幕坐标 (x, y) 对应的显卡偏移地址graphics_mode_offset的计算公式为:
        graphics_mode_offset = y * 320 + x
        
  • CPU

    • 算术逻辑单元 (ALU):算术、逻辑和移位运算
    • 控制单元 (CU):取指令、解释指令、执行指令
    • 寄存器 (register):可以理解为 CPU 下的全局变量,CPU 中只有它是可编程控制的

    • 总线 (bus):将 CPU 与外部器件连接起来的导线,分为 3

      • 地址总线:
        • 若有 \(N\) 根地址线,则 CPU 最多可访问 \(2^N\) 个内存单元
        • 它的宽度决定了 CPU 的寻址能力
      • 数据总线:
        • 若数据总线位宽为 \(N\),则 CPU 一次可传送 \(N\) 位数据
        • 它的宽度决定了 CPU 的数据传送量
      • 控制总线:
        • 对内存的读写主要由“读信号输出”和“写信号输出”的控制线分别负责
        • 它的宽度决定了 CPU 对系统中其他器件的控制能力
    • n 位(一般是 2 的幂)CPU 具有以下结构特性:

      • 运算器一次最多处理 n 位数据
      • 寄存器的最大宽度为 n
      • 寄存器和运算器之间的通路为 n
    • CPU 的具体实现可以参考我的计组笔记
  • 主板:每台 PC 都有一块主板,主板上有核心器件和一些主要器件,它们之间通过总线连接。这些器件包括:CPU、内存、外围芯片组、扩展插槽(一般插有 RAM 内存条和各类接口卡)等

  • 接口卡:能够直接控制外部设备的工作,通过总线与 CPU 相连,使得 CPU 能够间接控制外部设备
    • 读:CPU I/O 设备相关端口读取信号,获取 I/O 设备的反馈信息
    • 写:CPU I/O 设备相关端口发送信号,将控制信号输出到 I/O 设备

数制⚓︎

关于二进制、八进制、十进制和十六进制的表示与转换就不再赘述了,这里就讲一下与汇编语言相关的内容。

汇编语言下各种进制的表示:

  • 二进制:用 B b 作为后缀
  • 八进制:用 Q q 作为后缀
  • 十进制:无需后缀
  • 十六进制:用 H h 作为后缀,若最高位是字母还需加前缀 0

注意

  • 前后缀不会存储在寄存器内
  • 为了表示方便,对于较长的数字,本笔记采用“每四位空一格”的方法表示数字,但在汇编语言中数字之间不得有空格

数据组织⚓︎

  • (bit):存储计算机数据的最小单位
  • 字节 (byte)
    • 存储计算机数据的基本单位
    • 可以表示 \([0, 255]\)\([00h, 0FFh]\))范围内的无符号数,或者 \([-128, 127]\)\([80h, 7Fh]\))范围内的符号数,或者 ASCII
    • 关键词db用于定义字节类型的变量或数组
    • 相当于 C 语言中的charunsigned char
  • (word)
    • 1 = 2 字节 = 16
    • 8 位称为低字节,高 8 位称为高字节
    • 可以表示
      • \([0, 65535]\)\([0000h, 0FFFFh]\))范围内的无符号数
      • \([-32768, 32767]\)\([8000h, 7FFFh]\))范围内的符号数
      • 16 位的段地址或 16 位的偏移地址
    • 关键词:dw
    • 相当于 C 语言中的short intunsigned short int
  • 双字 (double word,简称 dword)
    • 1 双字 = 2 = 4 字节 = 32
    • 0-15 位称为低字,16-31 位称为高字,0-7 位称为低字节,24-31 位称为高字节
    • 可以表示
      • \([0, 4294967295]\)\([0000h, 0FFFFFFFFh]\))范围内的无符号数
      • \([-2147483648, 2147483647]\)\([80000000h, 7FFFFFFFh]\))范围内的符号数
      • float类型的小数
    • 关键词:dd
    • 相当于 C 语言中的long intunsigned long int
  • 四字 (quadruple word,简称 qword)

    • 1 四字 = 4 = 8 字节 = 64
    • 可以表示
      • \([0, 0FFFFFFFFFFFFFFFFh]\)\([0, 2^{64}-1]\))范围内的无符号数
      • \([8000000000000000h, 7FFFFFFFFFFFFFFFh]\)\([-2^{63}, 2^{63}-1]\))范围内的符号数
      • double类型的小数
    • 关键词:dq
    • 相当于 C 语言中的long longdouble

      注:旧版 VC 中不支持long long,可以用__int64替代

  • 十字节 (ten byte,简称 tbyte)

    • 字面意思,宽度为 10 字节,即 80
    • 可存放 80 位小数
    • 关键词:dt

零扩充与符号扩充⚓︎

  • 无符号数的扩充称为零扩充:高位补 0
  • 符号数的扩充称为符号扩充:正数高位补 0,负数高位补 1

评论区

如果大家有什么问题或想法,欢迎在下方留言~