若余相思 发表于 2017-7-19 16:06:44

《汇编语言》第五章

1、表示内存单元,段地址在ds,偏移地址在bx寄存器中
2、loop 在汇编指令中表示循环
3、()表示()里面的内容,即里面的数据。可以(寄存器)、(段寄存器)和(内存单元的物理地址)
4、idata 表示常量
5.1节【BX】
mov ax,
功能:把在段地址为(ds),偏移地址为(bx)的内存单元的内存送入ax中,即((ds) * 16 + (bx)) = (ax)
反之亦然

inc bx
功能:(bx) + 1 ,和add bx, 1差不多

5.2节 loop指令
loop 格式:loop 标号,要执行loop指令要执行这两步操作
1、(cx) = (cx) - 1
2、判断cx中的值,不为0则转至标号处继续执行程序,如果为0则向下执行

如:
assume cs : code
code segment
        mov ax, 2H
        mov cx, 11
s:add ax, ax
    loop s
       
        mov ax, 4c00H
        int 21H
code ends
end

进行2的12次方的计算,把结果放在ax中
循环的过程:



可见
(1)循环的次数放在cx中
(2)loop 标号要在循环程序段后面
(3)要循环的程序要在标号和loop 标号之间
框架如下:

标号:
        循环程序
        loop 标号

5.3节 在debug中跟踪loop指令实现的循环程序
问题:计算FFFF: 6单元的数据乘以3,结果存在dx中
答案:
assume cs : code
code segment
        mov ax, 0ffffH
        mov ds, ax
        mov bx, 6
        mov al,
        mov ah, 0
        mov dx, 0
        mov cx, 3
       
s:add dx, ax
        loop s
       
        mov ax, 4c00H
        int 21H
       
code ends
end
注意到mov ax, 0ffffH,FFFFH地址要这样写0FFFFH,因为在汇编程序中,数据不能以字母开头。如:“9138H”在汇编程序中可以直接写为:“9135H”,而“A000H”在汇编程序中要写为“0A000H”
下面我们对该程序进行跟踪:

看到程序在CS: IP中,用U命令查看到对应的机器指令

这是执行了前三条指令的图示
可知道FFFF6的内存的数据是32H

上图的指令完成了对dx和cx的初始化和设置循环次数

当执行了add dx,ax之后,(IP) = 0014H,即CS: IP 指令14bc: 14处的指令,接着执行“loops”的指令,第一步,先将(CS) - 1,(CS) = 2,第二步,因为(CS)不等于0,将IP设置为0012,即CS:IP指向14bc:12的地址,执行add dx, ax。接着将重复“add dx,ax“和”loop 0012“直到CX = 0为止,如下图


5.4节 Debug和汇编编译器masm对指令的不同处理
(1)在debug中编程实现
mov ax, 2000
mov ds, ax
mov al,
mov bl,
mov cl,
mov dl,
(2)汇编程序实现
assume cs :code
code segment
        mov ax, 2000H
        mov ds, ax
        mov al,
        mov bl,
        mov cl,
        mov dl,
       
        mov ax, 4c00H
        int 21H
code ends
end
       
       
(1)中在debug中的情况


(2)在debug中的情况


从中可以看出debug和masm编译器对形如:mov al,【0】,mov bl,【1】这类指令在解释上的不同,debug将他解释为【idata】是一个内存单元,而编译器将【idata】解释一个常量
那么如何解决子啊编译器中表示内存单元呢?
比如我们可以这样做
mov ax, 2000H
        mov ds, ax
        mov bx, 0
        mov al,
可是这样比较繁琐
我们用另一种方法,在内存单元之前显式的给出段地址所在的段寄存器,如:
mov ax, 2000H
        mov ds, ax
        mov al, ds:

比较一下汇编程序中一下指令的含义:


5.5节 loop和【BX】的联合应用
问题:计算FFFF:0~FFFF:b单元中的数据和,结果存放在dx中
答案:
assume cs :code
code segment
        mov ax, 0ffffH
        mov ds, ax
        mov bx, 0
        mov dx, 0
        mov cx, 12h
       
S:mov al,
    mov ah, 0
        add dx, ax
        inc bx
        loop s
       
        mov ax, 4c00H
        int 21H
code ends
end
       
       
本质就是:找到所在的存储单元的地址,然后将该地址的内容方在一个通用寄存器中,然后将另一个寄存器置0,然后让两个寄存器相加。

5.6 节 段前缀
mov ax, ds:
mov ax, es:
mov ax, es:
mov ax, ss:
用以显式的指明内存单元的段地址:”es“,”ds“,”cs“,”ss“,在汇编语言中称为段前缀

5.7节 一段安全的空间
mov ax, 1000H
mov ds, ax
mov al, 0
mov ds:, al
这样的做法是危险的,因为我们不知道10000H这个内存中有没有存放其他指令,如果10000H中存放一些重要的系统数据和代码,”mov ds:, a“将引发错误。
5.7节的总结:
(1)我们需要向一段内存写入内容;
(2)这段内存空间不应存放其他数据和代码;
(3)DOS方式下,一般情况,0:200~0:2FF空间没有其他系统或其他程序的数据或代码;
(4)以后在写入内存数据和代码的时候,用0:200~0:2FF这段空间。

5.8节 段前缀的使用
问题:将内存FFFF:0~FFFF:b单元中的数据复制到0:200~0:20b单元中
答案:
assume cs : code
code segment
        mov ax, 0ffffH
        mov ds, ax
       
        mov bx, 20H
        mov es. ax
       
        mov bx, 0
        mov cx, 12
       
s:mov al,
    mov es:, al
        inc bx
        loop s
       
        mov ax, 4c00H
        int 21H
       
code ends
end
思路:找到双方的内存单元地址,然后将一方的内容放在一个寄存器中,然后将寄存器的内容放在所最终要放在的内存单元中,偏移地址用循环来自增。

总结:
(1)【BX】也是表示内存单元,偏移地址在BX寄存器中的数据
(2)loop 标号 功能是循环,循环次数放在cx中,第一步(CX) - 1 = (CX),判断(CX)是否为0,不为0则执行标号:之后的指令
(3)在汇编程序中mov ax , 表示将0放在ax寄存器中,要表示内存单元要mov ax, ds:或,mov ax, ,段地址在ds中。
(4)mov ax, ds:中的ds是段前缀
(5)操作内存时要注意内存地址的表示方式
页: [1]
查看完整版本: 《汇编语言》第五章