汇编语言学习第8章

1.  数据处理的两个基本问题

    这已经是老生常谈啦, 数据处理有两个关键的问题:

第一,需要处理的数据在 什么地方?

第二呢,是需要处理的数据 有多长?

    这两个问题 是我们 编程的基础, 如果不知道数据从何而来,其规模大小

再优秀的计算机也是会无能为力啦

    在这里先定义两个符号 reg 和 sreg :

    reg  表示寄存器  : ax, bx, cx, dx 以及它们切割出来的 8位寄存器, sp, bp, si, di

    sreg 表示段寄存器: ds, ss, cs, es

 

    上面的寄存器,只有bp没有介绍过,先单独说一下 bp 这是一个功能,类似于 bx 的 寄存器,只不过,不是通用寄存器

bp 的段地址 存放在 ss 中, 允许 sreg:[bp] 进行内存访问

 

先来解决第一个问题,数据在什么地方?

    绝大部分 机器指令 都是用来处 理处理数据 的 指令,毕竟计算机设计的初衷就是 数据处理

    数据处理指令分类三类:

        读取 写入 运算

    对于 机器指令 来说呢,它不关心数值,只关心 机器指令执行前一刻,数据的位置

    而在这一时刻, 数据一般会在 3 个位置: CPU 内部 内存 端口

    mov bx, [0]         内存

    mov bx, ax          CPU 内部,寄存器

    mov bx, 01H         CPU 内部,指令缓冲器

    那么,在 汇编语言 中如何表达 数据所在位置?

        立即数:

            对于直接包含在 指令 中的 数据, 汇编称为立即数

            mov ax, 1

            add ax, 200h

            or ax, 0DFH

            mov al, 'a'

 

        寄存器:

            数据 存储在寄存器内部

        mov ax, bx

        mov ds, ax

        push ds

        pop sp

 

        

        SA + EA:

            bx 的默认的 sreg 为 ds

            bp 的默认的 sreg 为 ss

            当然也允许 目前指出 sreg

            mov ax, ds:3[bx+si]

            mov dx, es:3[bp+di]

 

    

        每个 数据小姐姐 都有一个家,有家就会有地址,汇编小姐姐 该如何找到 数据小姐姐 的家呢

    有 5 种方法,分别是:     

        直接寻址法:         [idata]

  寄存器相对寻址法:[bx]

        寄存器间接寻址法:   [bx].idata(结构体)

                            idata[si](数组)

                            [bx][idata](二维数组)

        基变寻址法:         [bx][si](二维数组)

        相对基变寻址法:     [bx].idata[si](表格结构中的数组)

                            idata[bx][si]

    

        下面我就来略微的解释一下这几种寻址方法(个人能力有限):

    某天,数据小姐姐约 CPU 出去玩, 数据小姐姐 直接 给了地址,说咱们在 这个地方见面,这就是 直接寻址法, 直接按着地址走就可以了

        如果数据小姐姐说 先去咖啡厅碰面(寄存器),然后再告诉你去哪玩,这就是 寄存器相对寻址法, 通过一个指针(寄存器)先访问指针,才能访问对应的数据

   如果数据小姐姐说 先去咖啡厅碰面(寄存器),然后走了几百米,才再告诉你去哪玩,这就是 寄存器相对寻址法, 通过一个指针(寄存器)先访问指针,才能访问对应的数据

        如果小姐姐说 先去咖啡厅然厅,然后去肯德基,最后再告诉你去哪玩,这个就是 基地址变址寻址法,通过 基地址 经过 两个 寄存器的组合后,访问数据

        如果小姐姐说 先去咖啡厅然厅,然后去肯德基,走了个几百米才告诉你去哪玩,这就是 相对基地址变址寻址法 通过 基地址 经过 两个 寄存器的组合后 又跑了一段路,访问数据

 

 

接下来解决下一个问题,数据的长度?

    其实,这个问题在之前就提到过了, mov ax, [bx] 是如何知道数据长度的? 当然是通过寄存器的位数

    但是 按照我们之前的设定 mov es:[bx], ds:[bx] 就无法正常运行了, 因为 CPU 无法感知到数据的大小,

    所以,这时候 新的声明方式就出现了, word / Byte ptr 声明 字/字节 类型的数据

    eg:

        mov Byte ptr es:[bx], ds:[bx]

        mov word ptr es:[bx], ds:[bx]

 

好了,到这里编程的基本问题算是解决了,接下去该学点新的指令了

 

div 指令:

    这是一个除法指令,与 add 和 sub 不同的是, div 对 除数 和 被除数 有着一定的约束条件

 

        除数:   有 8位 和 16位 两种, 在一个 reg 或者 内存单元 中

        被除数: 默认放在 AX 或 AX + DX 中 如果 除数 为 16 位,则被除数 32 位, AX 存储低位, DX 存储高位

                如果除数 8 位, 则被除数 16 位

        结果:   除数为 8 位, AL 存商, AH 存余数

                除数为 32 位, AX 存商, DX 存余数

    思考一下: div FFFFH, 1 会怎么样,当然是因为,除数过大会溢出

 

伪指令 dd:

    表示 该数据为双字

    eg:

        data segment

            db 1

            dw 1

            dd 1

        data ends

 

 

操作符 dup:

    定义重复数据

    dd 3 dup (2)    == dd 2,2,2

    dw 3 dup ('ABC','abc') === dw 'ABCabcABCabcABCabc'

 

posted @ 2020-03-09 15:45  秦_殇  阅读(191)  评论(0编辑  收藏  举报