读书笔记:汇编语言 第三版 王爽 清华出版社 前言 章一 章二 章三 章四 章五

汇编语言
第三版
王爽
清华出版社

文档记录
    创建        2020年8月9日15:21:11
    初稿完成     2020年9月5日15:38:22

前言
    汇编语言,CPU提供的机器指令的助记符的集合
        不同处理器,机器指令可能不同,汇编语言就可能不同
    从事计算机科学方面的工作,汇编语言必不可少
        汇编语言是人与计算机沟通的最直接方式,描述了机器执行的指令序列
    汇编语言的学习
        方式,针对一种常用且结构简洁的处理器
        目的
            获得底层编程的体验
            深刻理解机器运行程序的机理
    目标处理器
        8086CPU
            纯粹的8086处理器,已不常见了
            任何与Intel兼容的CPU,都可以8086的方式工作
    Intel微处理器的发展
        过程
            8080、8086/8088、80186、80286、80386、80486、Pentium、Pentium II、Pentium III、Pentium4
        8086/8088(重要产品)
            8086和8088,略有区别的功能相同的CPU
            8088被IBM用在第一台微机上,该微机的结构成为以后微机的基本结构
            不能用于实现一个完善的多任务操作系统
        80286
            开始支持多任务系统,对8086/8088的兼容不好
            IBM基于80286开发了多任务系统OS/2,结果犯了战略错误
            其缺陷在于,只提供了实模式和保护模式
                不能在保护模式下运行8086程序,而是需要重启运行DOS系统,然后运行8086程序
        80386(重要产品)
            支持多任务系统,对8086/8088的兼容好
            支持三种工作模式
                实模式,相当于一个8086
                保护模式,支持多任务环境,提供保护机制(与VAX等小型机类似)
                虚拟8086模式,用于较好的兼容8086/8088
                    可从保护模式切换到一种8086工作模式
                    便于在保护模式下运行一个或多个原8086程序
            工作模式的应用
                在Intel系列CPU的PC上
                开机时,CPU处于实模式
                如果是DOS操作系统,CPU继续保持实模式
                如果是Windows操作系统,CPU将切换到保护模式
                若在Windows中运行一个DOS程序,则Windows会将CPU切换到虚拟8086模式运行该程序
        当前CPU
            真正有效力的工作模式是保护模式
            实模式仅用于兼容
            虚拟8086模式,仅用于兼容的友好性
    我们的编程环境是CPU的实模式
        在保护模式下编程,会涉及其他较为复杂的知识,不便于集中于汇编语言的学习
    教学思想
        学习是一个循序渐进的过程
        不以循序渐进的方式学习
            将出现盲目探索和不成系统的情况
            最终获得零散的知识,而不是建立系统的知识结构
            不能达到学习的深度
        不以循序渐进的方式组织教程,没有处理好知识的依赖性
            给人一种不能通透的感觉
            反复看书,也不能深入下去
        计算机是一门交叉学科,处理不好与主题相关的内容,将影响读者的理解
            本书采用知识屏蔽的方法,对教学内容进行了最小化分割,降低了知识的耦合性,便于掌握
        自底向上,逐步积累
    本书具有较强的前后依赖性,学习时应该步步为营
    内容特点
        本书以学习目的(原理和意识)为中心,组织内容
            不讲解每条指令的功能,那属于指令手册的内容
                本书关注于重要指令和关键概念
            编程的平台是硬件,而非操作系统
                在裸机上编程

第一章 基础知识
    1.0 概述
        汇编语言,是直接工作在硬件上的编程语言
        只有了解硬件系统的结构,才能有效地使用汇编语言进行编程控制
            硬件的介绍,是随着需要展开的,不进行全面和深入的论述
        汇编语言的重点
            利用硬件系统的编程结构和指令集,有效灵活地控制系统进行工作
        微机原理和接口
            PC机和CPU物理结构和编程结构的全面研究
        计算机组成原理
            计算机一般的结构、功能、性能的研究
    1.1 机器语言
        机器语言,机器指令的集合
        机器指令
            逻辑上,一组二进制数,机器可以正确执行的命令
            物理上,一组高低电平,可以使计算机电子器件受到驱动,而进行运算
        计算机,可以执行机器指令进行运算的机器
            由CPU(Central Processing Unit,中央处理单元)和受其直接或间接控制的芯片、器件、设备组成的计算机系统
        CPU负责机器指令的执行
        不同的处理器,其硬件设计和内部结构不同
            需要不同的电平脉冲进行控制,以使其工作
            对应拥有不同的机器机器指令集
    1.2 汇编语言的产生
        使用机器语言编程的问题
            难以书写和阅读
        汇编语言的主体是汇编指令
            汇编指令与机器指令(机器码),一一对应,仅在指令的表示方法上不同
            汇编指令,是机器指令便于书写和阅读的格式
        执行
            汇编指令编写的源程序,需要先使用汇编编译器,将之转换为机器码
            然后被计算机执行
    1.3 汇编语言的组成
            汇编指令,机器指令的助记符,作为核心和主体,决定了汇编语言的特性
            伪指令,不对应机器指令,由编译器使用
            其他符号,如+-*/,不对应机器指令,由编译器使用
    1.4 存储器
        存放程序运行时CPU所使用的指令和数据
    1.5 指令和数据
        指令和数据,都是应用上的概念,在物理上都表示为一组二进制
    1.6 存储单元
        存储单元,存储器的基本组成,从0开始编号
        存储单元的地址,即存储单元的编号
        容量,一个字节(Byte),8个位(bit,比特)
        单位转换
            1TB = 2**10 GB
                = 2**20 MB
                = 2**30 KB
                = 2**40 B
    1.7 CPU对存储器的读写
        CPU向外读写数据时,包含的信息
            地址信息,存储单元的选择
            控制信息,外部器件(芯片)的选择和读写操作的选择
            数据信息,读操作的地址,写操作的数据
        总线
            CPU和其他芯片进行交互的一组导线
                CPU通过自身的管脚,与主板上的总线相连
            逻辑分类,根据交互的信息类别
                地址总线
                控制总线
                数据总线
        读操作
            汇编指令
                MOV AX, [3]
            8086CPU机器指令
                10100001        # 指令类型
                00000011        # 指令操作数
                00000000        
            指令流程
                CPU向地址总线,写地址
                CPU向控制总线,写内存读取命令
                CPU从数据总线读数据
        写操作
            CPU向地址总线,写地址
            CPU向控制总线,写内存写入命令
            CPU项数据总线写数据
    1.8 地址总线
        地址总线上的数据,描述了存储单元的地址
        地址总线的宽度N,即总线上的导线数N,决定了CPU的寻址能力,为2**N
        例子
            8080    16
            8088    20
            8086    20
            80286   24
            80386   32
    1.9 数据总线
        CPU通过数据总线,与外部进行数据交换
        数据总线的宽度,决定了CPU的数据传输速度
        8088CPU的数据总线宽度为8
        8086CPU的数据总线宽度为16
        例子
            8080    8
            8088    8
            8086    16
            80286   16
            80386   32
    1.10 控制总线
        CPU通过控制总线,选择外部芯片和操作类型
        控制总线的宽度,决定了CPU对外部器件的控制能力
        组成
            外部器件的选择线
            读控制线
            写控制线
    1.11 内存地址空间
        所有可寻址的内存单元,构成了内存地址空间
    1.12 主板
        通过总线连接计算机核心器件的插板
            CPU、存储器、外围芯片组、扩展插槽(一般插有RAM和接口卡)
    1.13 接口卡
        作为CPU和外设之间的中间层,信号适配器
            输入,CPU发出的二进制数字信号
            输出,外设的工作信号,常是模拟信号
        接收CPU命令,控制外设工作
        如显卡、网卡
    1.14 各类存储器芯片
        RAM
            主存
                用于存放CPU使用的绝大部分程序和数据
                位置
                    主板上的RAM
                    扩展插槽上的RAM
            接口卡上的RAM
                对大批量的输入、输出数据进行暂时存储
                如显卡上的RAM,一般称为显存
        ROM
            主板和接口卡上的ROM
                保存BIOS
                    BIOS,是软件系统,由主板和各类接口卡厂商提供
                    使用BIOS程序,能够使用硬件进行基本的输入输出
    1.15 内存地址空间
        在8位虚拟机中,《but how it know》
            只有一个物理存储器,即主存
            其余存储器和设备,被作为外设进行访问
                这些外设通过一对寄存器(地址寄存器和数据寄存器),与CPU交换数据
                包括键盘适配器,显示器适配器
        在8086中
            包含多个物理存储器,但统一为一个逻辑存储器
            所有存储器芯片,统一相同对待,对应了相同的指令
            所有的物理存储器,在功能上被CPU看作是一个逻辑整体
                称为逻辑存储器,也称为内存地址空间
                地址空间,被各存储芯片划分
                把对物理存储单元的二维访问,转化为对逻辑存储单元一维访问
            对指定逻辑空间的读写,转换为对所属存储芯片的读写
            CPU和物理存储器之间有地址总线,其上指定了逻辑存储单元的地址
                地址总线的宽度,决定了内存地址空间的大小
            不同计算机系统中,内存地址空间的划分情况不同
                如8086PC中
                    主存    00000~9FFFF
                    显存    A0000~BFFFF
                    各类ROM C0000~FFFFF
        都使用地址总线,完成对外设的访问
        内存访问和外设访问,对应了不同的指令
        外设访问的标准一样,都是一对寄存器交互,不同的是
            8位虚拟机中,仅主存被实现为内存访问,其余被实现为外设访问
            8086中,存储芯片都实现为内存访问,其余被实现为外设访问(端口访问)

第二章 寄存器
    2.0 概述
        CPU组成
            运算器,信息处理
            控制器,根据指令控制器件工作
            寄存器,信息存储
            内部总线
                内部总线,连接CPU内部各器件
                外部总线,连接CPU和主板上其他器件
        通过寄存器的存取,完成对CPU的控制和使用
        8086CPU的寄存器,共14个,皆16位
            通用寄存器,AX,BX,CX,DX
            段寄存器,CS,SS,DS,ES
            其他,SI,DI,SP,BP,IP,PSW
    2.1 通用寄存器
        用于通用目的,存放一般性数据
        为了兼容为上一代8位寄存器CPU写的程序,一个16位的通用寄存器,可以拆成两个独立的8位寄存器使用
            AX,AH和AL
            BX,BH和BL
            CX,CH和CL
            DX,DH和DL
            高八位对应H,低八位对应L
    2.2 字在寄存器中的存储
        一个字节,可存在一个8位寄存器中
        一个字,两个字节,可存在一个16位寄存器中
            高位字节放高8位寄存器
            低位字节放低8位寄存器
    2.3 几条汇编指令
        MOV
            格式,mov A(寄存器名称), B(寄存器名称或常量)
                不分大小写
            含义,将B中值或B传入A中
        ADD
            格式,mov A(寄存器名称), B(寄存器名称或常量)
                不分大小写
            含义,将B中值或B加入A中
        注意
            操作数,A和B,需要位数一致,或8位或16位
            对于通用寄存器,计算中出现进位(超过16位)
                多出位不能保存,可通过标志寄存器发现
            对于低8位寄存器,计算中出现进位(超过8位)
                多出位不会保存在高8位寄存器中,可通过标志寄存器发现
                高8位寄存器和低8位寄存器,相互独立使用
    2.4 物理地址
        内存单元,在内存地址空间中,拥有唯一的地址,被称为物理地址
        CPU通过地址总线,传输的就是物理地址
        注意
            内存 == 主板RAM + 器件ROM + 器件RAM
    2.5 16位结构的CPU
        N位结构的CPU的特性
            处理位数,运算器一次可处理的最大位数,为N
            存储位数,寄存器的宽度,为N
            传输位数,运算器和寄存器间通道宽度,为N
    2.6 8086CPU给出物理地址的方法
        方法
            物理地址 = 段地址 * 16 + 偏移地址
            20位    = 16位  << 4 + 16位
        步骤
            把两个16位寄存器中的值,传入地址加法器中
            将地址加法器的结果输出到地址总线上
    2.7 "物理地址 = 段地址 * 16 + 偏移地址"的本质含义
        物理地址 = 基址 + 偏址
        两个低位数合成一个高位数
            20位 = 16位 << 4 + 16位
        目标定位:自顶向下,逐步细化
            1MB(2**20)空间,分割成64KB(2**16)份
                段地址,确定第几份
                偏移地址,确定份内的第几个
    2.8 段的概念
        段(Segment),起始地址为16的倍数的一段连续内存
        特点
            段空间中的内存单元
                段地址相同
                偏移地址不同
            段空间最大长度,为偏址的容量,64KB(2**16)
        一个内存单元,对应一个物理地址,但可有多个不同的合成方法
            常表示为"段地址:偏移地址","XXXX:XXXX"
    2.9 段寄存器
        用于保存段地址的寄存器,在物理地址合成时被使用
            CS, DS, SS, ES
    2.10 CS和IP
        CS:IP
            组合地址,表示下一条指令的内存地址
            CS,代码段寄存器,存储指令的段地址
            IP,指令指针寄存器,存储指令的偏移地址
        8086CPU工作流程
            从CS:IP指向的内存单元,读取指令并存入指令缓冲器
            IP自增指令长度,指向下一地址
            执行指令
        8086CPU启动或复位后
            CS被置为FFFFH
            IP被置为0000H
            故启动或复位后的第一条指令在FFFF0
    2.11 修改CS、IP的指令
        常量绝对跳转
            指令,jmp XXXX:XXXX
            效果
                CS=XXXX
                IP=XXXX
                CPU与内存间数据传输
        寄存器相对跳转
            指令,jmp 寄存器
            效果
                IP=寄存器
                CPU内寄存器间数据传输
    2.12 代码段
        存放指令的段
        执行代码,只需跳转到代码段
    2.13 查看CPU和内存,用机器指令和汇编指令编程
        DOSBox
            模拟一个完整的x86PC,包含声音和DOS系统
            目的,为不支持DOS的操作系统,提供一个DOS程序的运行平台
        Debug
            DOS、Windows都提供的实模式(8086方式)程序的调试工具
            可以查看CPU寄存器、内存,在机器码级别跟踪程序的运行
            功能
                R命令    CPU寄存器的查看和修改
                D命令    内存的查看
                E命令    内存的修改
                U命令    将内存中机器指令翻译成汇编指令
                T命令    指令一条机器指令
                A命令    以汇编指令的格式,向内存中写入机器指令
            举例
                R
                R IP
                D           => D DS:default 7F    
                D 1         => D DS:1 7F
                D 1000:1    => D 1000:1 7F
                D 1000:1 8  => D 1000:1 8
                E 1000:0 1 2 3 4 5
                E 1000:8
                E 1000:10 1 "HELLO" 2 "WORLD" 3 "HI"
                E 1000:0 B8 01 00 B9 02 00 01 C8
                U 1000:0 1F
                R CS
                R IP
                T
                T
                T
                A 1000:0

第三章 寄存器(内存访问)
    3.1 内存中字的存储
        小端法
            高8位,高地址
            低8位,低地址
        大端法
            高8位,低地址
            低8位,高地址
        N地址字单元
            起始地址为N的两个连续内存单元
    3.2 DS和[address]
        访问内存单元
            DS,存放数据访问的段地址
                8086CPU硬件设计,决定了不能直接将常量传入段寄存器
            [address],在MOV指令中表示数据访问的偏移地址
        例子
            MOV BX, 1000H
            MOV DS, BX
            MOV AL, [0]
    3.3 字的传送
        8086CPU是16位机构的,CPU和内存之间能够一次性传输16位数据
        若CPU给出8位寄存器,则进行一个字节传输
            内存为物理地址指向的内存单元
            MOV AL, [0]
            MOV [0], AL
        若CPU给出16位寄存器,则进行2个字节传输
            内存为物理地址指向的连续两个内存单元
            MOV AX, [0]
            MOV [0], AX
    3.4 mov、add、sub指令
        在debug中实验指令的汇编结果(A)
        MOV指令
            MOV 寄存器, 数据
            MOV 寄存器, 寄存器
            MOV 寄存器, 内存
            MOV 内存, 寄存器
            MOV 段寄存器, 寄存器
            MOV 寄存器, 段寄存器
            MOV 段寄存器, 内存
            MOV 内存, 段寄存器
            段寄存器,不支持送入常量数据,不支持段寄存器间传输
        ADD指令
            ADD 寄存器, 数据
            ADD 寄存器, 寄存器
            ADD 寄存器, 内存
            ADD 内存, 寄存器
        SUB指令
            SUB 寄存器, 数据
            SUB 寄存器, 寄存器
            SUB 寄存器, 内存
            SUB 内存, 寄存器
    3.5 数据段
        存储数据的段
    3.6 栈
        栈,存储空间,具有特殊访问方式,先进后出,后进先出
        状态
            存储空间
            栈顶指针
            栈底指针
        操作
            入栈
            出栈
    3.7 CPU提供的栈机制
        CPU
            提供指令,支持以栈的方式访问内存
                以字为操作对象
                入栈和出栈
            通过SS:SP形成当前栈的栈顶地址
                SS:SP始终指向栈顶元素
        入栈
            PUSH 寄存器或段寄存器或内存
                SP -= 2
                SS:SP = 寄存器或段寄存器或内存
            栈顶移向低地址
        出栈
            POP 寄存器或段寄存器或内存
                寄存器或段寄存器或内存 = SS:SP
                SP += 2
            栈顶移向高地址
    3.8 栈顶越界的问题
        越界,包含出栈越界和入栈越界
        CPU会基于当前栈顶地址,做一些操作,但不在乎是否超过栈的边界,其有效性需要程序逻辑维护
            如同CS:IP指向指令地址,会按照规则进行变化,其有效性需要程序逻辑维护
    3.9 push、pop指令
        使用栈指令之前,需要进行栈顶设定,初始为空栈
            如
                mov ax, 1000h
                mov ss, ax
                mov sp, 0010h
        栈指令
            是一种内存传送指令
                寄存器与内存之间
                内存地址由SS:SP决定
                指令会更新SP的值
                    栈的最大空间范围,0~FFFFH
            支持内存到内存
            包含两个动作
                SP更新(+-2)和数据传送
        SS:SP始终指向栈顶元素
    3.10 栈段
        储存栈的段
        段的概念,是一种连续内存区域的使用规划
            或用于存储指令,让CS:IP指向该内存区域
            或用于存储数据,让DS:[address]指向该内存区域
            或用于存储栈,让SS:SP指向该内存区域
    3.11 用机器指令和汇编指令编程
        在debug中,可以使用段寄存器名字表示段地址
            如 D DS:0
            如 D CS:0
            如 D SS:0
        debug的T命令在执行修改寄存器SS的指令时,下一条指令也会紧接着执行
            原因,中断机制
            如
                MOV AX, 2000
                MOV SS, AX
                MOV SP, 10
                MOV AX, 3123
        debug进程中,包含两部分程序——调试程序和debug控制程序
            CPU在两份程序之间,不断切换执行,切换时会保存CPU现场信息
            使用debug调试时,小心不要相互干扰
        debug调用T指令调试时会产生中断,保存现场时依次把标志寄存器、cs、ip保存在栈中
    
第四章 第一个程序
    4.1 一个源程序从写出到执行的过程
        编程
            使用文本编辑器,用汇编语言,编写汇编源程序
            产生一个包含源程序的文本文件
        编译连接
            使用汇编语言编译器,对源程序进行编译,产生目标文件
            使用连接程序,对目标文件进行连接,产生可执行文件
                可执行文件的组成
                    程序(机器码)和数据
                    相关描述信息
        执行可执行文件中的程序
            操作系统根据可执行文件中的描述信息,将可执行文件中的机器码和数据载入内存
            相关初始化,如设置CS:IP
            CPU执行程序
    4.2 源程序
        0. 例子
            assume cs:codesg

            codesg segment
                mov ax, 01234h
                mov bx, 0456h
                add ax, bx
                add ax, ax

                mov ax, 4c00h
                int 21h
            codesg ends

            end
        1. 伪指令
            汇编语言源程序中,分为
                汇编指令,对应机器码,最终被CPU执行
                伪指令,被编译器用于编译工作
            段定义指令
                段名 segment
                段名 ends
            程序结束指令
                end
                编译器看到end指令,就结束对源程序的编译
            assume
                assume 段寄存器名称:段名
                假设指定段与指定段寄存器有关联
                非必须
        2. 源程序中的程序
            源程序文件中所有内容,称为源程序
            源程序中终由计算机执行、处理的指令或数据,称为程序
        3. 标号
            如段名
            一个标号,指代一个地址
        4. 程序的结构
            源程序由多个段构成
            可在段中存放代码、数据,可作为栈空间
            编程步骤
                定义段
                定义end
                定义段关联
        5. 程序返回
            程序在DOS下的运行过程
                程序P2在可执行文件中
                一个正在运行的程序P1,将P2从可执行文件中载入内存
                P1将CPU控制权交给P2
                P2开始运行,P1暂停运行
                P2运行结束,应将CPU控制权还给P1
                P1继续运行
            程序返回
                一个程序结束,将CPU控制权还给使之运行的程序的过程
                实现指令
                    mov ax, 4c00h
                    int 21h
        6. 语法错误和逻辑错误
            语法错误,一般是程序在编译时发现的错误
            逻辑错误,一般是程序在运行时发生的错误
    4.3 编辑源程序
        DOS下可使用edit
        环境准备——DOSBox
            安装DOSBox
            创建目录c_disk
            下载masm611.rar,并解压到c_disk
                https://sourceforge.net/projects/masm611/
            在DOS环境下挂载c_disk到C盘,可尝试自动执行
                MOUNT C D:\programs\system\DOSBox-0.74\c_disk
                C:
            切换到masm安装目录
                masm611/disk1/
            运行setup.exe进行安装
                注意选择操作系统 MS-DOS/Microsoft Windows
        环境准备——VMware
            下载并安装,MS-DOS7.10完整安装光盘.ISO
            复制masm611安装目录到DOS系统
                编辑虚拟机设置
                硬件选项卡
                硬盘
                磁盘实用工具
                将该虚拟机磁盘映射到本地卷
                映射
                以只读模式打开文件(推荐)(R)的对勾去掉
                确定(默认映射到驱动器Z)
                文件复制
                取消映射
            切换到masm安装目录
                masm611/disk1/
            运行setup.exe进行安装
                注意选择操作系统 MS-DOS/Microsoft Windows
            添加Path
                Path %Path%;C:/masm611/bin/
    4.4 编译
        masm.exe
    4.5 连接
        link.exe
        连接的作用
            源程序很大,拆分为多个源程序文件分别进行编译
                使用连接程序,将多个目标文件连接成一个可执行文件
            程序中调用了库文件中的子程序
                需要将库文件和目标文件连接成一个可执行文件
            目标文件中有些内容不能直接用来生成可执行文件
                连接程序将这些内容处理为最终的可执行信息
                故目标文件始终需要进行连接处理
    4.6 以简化的方式进行编译和连接
        masm 1;
        link 1;
    4.7 1.exe的执行
        1
    4.8 谁将可执行文件中的程序装载进入内存并使它运行?
        操作系统的外壳
            操作系统,是一个庞大的、复杂的软件系统,由多个功能模块组成
            操作系统一般会提供一个称为shell的程序,用户使用该程序来操作计算机系统
            DOS有一个程序command.com,称为命令解释器,是DOS的shell
            DOS系统的运行
                DOS启动时,先完成初始化工作,然后运行command.com
                command.com完成一些任务后,在屏幕显示提示符,等待用户输入
                用户输入命令,command.com执行,完成后在屏幕显示提示符,等待用户输入
                用户执行程序
                    command查找到可执行文件
                    加载可执行文件中的程序到内存中
                    设置CS:IP为程序入口
                    command暂停运行,CPU运行程序
                    程序运行结束后,返回到command
                    在屏幕显示提示符,等待用户输入
        汇编编程的流程
            Edit -> masm -> link -> command -> CPU
            编辑     编译     连接     加载       运行
    4.9 程序执行过程的追踪
        跟踪原理
            DOS中执行程序
                command加载程序,并将CS:IP指向程序入口后,就放弃了CPU控制权
            Debug中调试程序
                Debug加载程序,并将CS:IP指向程序入口后,未放弃CPU控制权,使能完成调试操作
        DOS中可执行文件(EXE)的加载
            command在内存中找到一个容量足够的段
                起始地址表示为SA:0
                称为空闲内存区
            command在空闲内存区的前256个字节中,创建数据区
                称为程序段前缀(PSP)
                DOS利用PSP与被加载程序通信
                地址范围,SA:0~SA:FF
            command在数据区后,载入程序
                起始地址表示为SA+10H:0
            初始化
                DS = SA
                初始化其他相关存储器
                    CX = 程序长度
                将CS:IP指向程序入口
            注意
                上述步骤未涉及重定位,因为与操作系统的关系较大,故不讨论
        Debug中调试程序
            command加载debug程序
            debug加载被调试程序
                Debug 1.exe
            调试操作
            被调试程序返回
                执行"int 21"需要使用P命令,而非T命令
                返回到debug
            debug程序返回
                Q命令
                返回到command

第五章 [BX]和loop指令
    5.0 概述
        寻址方式
            常量寻址,[0]
                mov ax, 0
                将DS:0开始的字,存入ax中
            变量寻址,[bx]
                mov ax, [bx]
                将DS:(bx)开始的字,存入ax中
                    (bx)表示bx中的值
        数据种类
            标记()
                解引用,地址转数据
                "(地址)",表示地址对应的存储设备中的数据
                "(ax)",表示ax中的数据
                "(10000h)",表示10000h中的数据
            数据
                数据直接表示数据
                mov ax, 1000h
                    将1000h存入ax
                    本质
                        数据存放在指令中
                        将((cs)*16+(ip)+1),存入ax
            地址
                数据表示存储设备地址,存储设备中有目标数据
                    寄存器
                        mov ax, bx
                        将bx中值,存入ax
                    内存
                        mov ax, [0]
                        将ds:0中值,存入ax
                        将((ds)*16+0),存入ax
            元地址
                数据表示存储设备A地址,存储设备A中有目标数据所在存储设备B地址,存储设备B中有目标数据
                    内存
                        mov ax, [bx]
                        将ds:bx中值,存入ax
                        将((ds)*16+(bx)),存入ax
            mov指令的操作对象,是两个存储设备
                或以地址指代
                或以机器码指代
        约定符号"idata",表示常量
    5.1 [BX]
        内存变址传送,只支持BX寄存器
        mov ax, [bx]
            (ax) = ((ds)*16+(bx))
        mov [bx], ax
            ((ds)*16+(bx)) = (ax)
    5.2 Loop指令
        格式
            loop label
        行为
            cx自减
            若cx!=0,则跳转到label,否则继续
        本质
            条件跳转指令
        功能
            一般用于实现循环
            模式
                    mov cx, 循环次数
                s:
                    循环执行的指令序列
                    loop s
    5.3 在Debug中跟踪用loop指令实现的循环程序
        在汇编源程序中,数据不能以字母开头,可在前加0表示
        在debug中
            使用P指令执行loop指令,则会一直执行到cs为0
            使用G指令执行,则会一直执行到指定地址
                如,G 0012H,则执行到CS:12H停
    5.4 Debug和汇编编译器masm对指令的不同处理
        同汇编指令,不同机器指令
            mov ax, [0]
                Debug,内存定址传送
                    区分
                        mov ax, [0]
                        mov ax, 0
                masm,内存常量传送
                    不区分
                        mov ax, [0]
                        mov ax, 0
        同机器指令,不同汇编指令
            内存定址传送1
                Debug
                    mov ax, [0]
                    不支持mov ax, ds:[0]
                masm
                    mov ax, ds:[0]
            内存定址传送2
                Debug
                    不支持mov ax, es:[0],可拆分为
                        es:
                        mov ax, [0]
                masm
                    mov ax, es:[0]
        同汇编指令,同机器指令
            内存变址传送1
                Debug
                    mov ax, [bx]
                    不支持mov ax, ds:[bx]
                masm
                    mov ax, [bx]
                    mov ax, ds:[bx]
            内存变址传送2
                Debug
                    不支持mov ax, es:[bx],可拆分为
                        es:
                        mov ax, [bx]
                masm
                    mov ax, es:[bx]
        简单讲
            在debug中,使用 mov ax, []
                若段地址非DS,则需提前声明
            在masm中,使用 mov ax, 段寄存器:[]
                段地址可通过DS,CS,SS,ES提供
    5.5 loop和[bx]联合应用
        把字节加到字中,可使用额外的寄存器进行中转
            mov ah, 0
            mov al, ds:[0]
            add dx, ax
        寄存器自增
            inc 寄存器
    5.6 段前缀
        在masm中,使用 mov ax, 段寄存器:[],段地址可通过DS,CS,SS,ES提供
            DS,CS,SS,ES被称为段前缀
    5.7 一段安全的空间
        在8086模式中,随意向一段内存空间写入内容是很危险的,因为这段空间中可能存放着重要的数据或代码
        例子
            代码
                assume cs:code
                code segment
                    mov ax, 0
                    mov ds, ax
                    mov ds:[26h], ax

                    mov ax, 4c00h
                    int 21
                code ends
                end
            在虚拟8086模式中,会出现报错窗口
            在实模式下,会引起死机
                EMM386 has detected error #17 in an application at memory address 00B8:E801
        内存写入考虑
            在操作系统中工作时,操作系统管理了所有的资源,包括内存
                向内存空间写入数据时,应使用操作系统分配给程序的空间,而不是直接用地址任意指定内存空间
            我们学习汇编语言的目的是,获得底层的编程体验,理解计算机底层的基本工作原理
                故应尽量直接对硬件编程,而不去理会操作系统
            选择
                学习操作系统时,在操作系统中安全、规矩地编程
                其他大部分情况下,应自由、直接地使用汇编语言去操作真实的硬件
                若想直接向内存写入数据,又不想出现系统异常
                    可选在0:200~0:2ff
                    在一般的PC机中,DOS方式下,DOS和其他合法程序一般不会使用该空间
                    为谨慎起见,进入DOS后,可使用debug查看该空间,确保全部为0(即未被使用)
        注意
            在纯DOS方式(实模式)下,可以不理会DOS,直接使用汇编语言去操作真实的硬件
                因为运行在CPU实模式下的DOS,没有能力对硬件系统进行全面严格地管理
            在Windows、Unix等运行于CPU保护模式下的操作系统,需要经过操作系统,才能用汇编语言去操作真实的硬件
                硬件被操作系统全面严格地管理了,通过CPU保护模式提供的功能
    5.8 段前缀的使用
        可使用CS,DS,SS,ES提供段地址
        例子,将ffff:0~ffff:b中的数据复制到0:200~0:20b
            assume cs:code

            code segment
                mov ax, 0ffffh
                mov ds, ax
                mov ax, 20h
                mov es, ax
                mov bx, 0
                mov cx, 0ch

            s:  mov al, ds:[bx]
                mov es:[bx], al
                inc bx
                loop s

                mov ax, 4c00h
                int 21h
            code ends

            end
    5.9 实验4 [bx]和loop的使用
        向内存0:200~0:23f传送数据0~3f
            assume cs:code

            code segment
                mov ax, 20h
                mov ds, ax
                mov bx, 0
                mov cx, 40h

            s: mov ds:[bx], bl
                inc bx
                loop s

                mov ax, 4c00h
                int 21h
            code ends

            end

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值