[汇编语言] [bx]和 loop指令学习笔记

    选择打赏方式

5.1[bx]

mov ax,[bx]
功能:bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将SAEA处的数据送入ax中。

即:(ax)=((DS)*16+(bx))
mov [bx],ax
功能:bx中存放的数据作为一个偏移地址EA,段地址SA默认在ds中,将ax中的数据送入内存SA:EA处。

即: ((DS)*16+(bx))=(ax)


其实很简单可以理解

mov ax,[bx]    ds存储段地址,bx为偏移地址,物理地址就是DS*16+bx(SA:EA),然后将这个物理地址中的值取出来放进AX寄存器

mov [bx],ax     ds存储段地址,bx为偏移地址物理地址同样是DS*16+bx(SA:EA),但是不取这个地址中的值,而是把ax中的值ds为机址bx为偏移的这个物理地址


[BX]作为操作数1的作用是将操作数2写入ds为段地址BX为偏移地址的内存单元

[BX]作为操作数2的作用是将操作数2的值作为地址,将地址中的值传入操作数1的寄存器中 


带[]和不带[]的区别

如:

bx中存放的数是40F6H,40F6H、40F7H两个单元中存放的数是22H、23H,则
mov ax,[bx];2223H传送到ax中
mov ax,bx;40F6H传送到ax中


5.2 Loop指令

TIM截图20180919104914.png

LOOP指令为循环指令,其格式为 LOOP 标号,当cx不为0的时候跳转到标号处循环同时cx=cx-1,如果标号为0则向下执行。(CX默认为循环计数器)


编程计算2^12

例子:

assume cs:code
code segment
    mov ax,2
    mov cx,11
s:  add ax,ax
     loops


    mov ax,4c00h
    int 21h
code ends
end


1.标号

标号s处有一条指令,add ax,ax用于累加,标号s代表该条指令的地址。

2.loop s

当cx寄存器中的值不为0的时候将跳转到标号处循环执行add ax,ax。当cx=0的时候,loop s不再跳转,将执行Loops后面的指令。 


用cx和loop实现循环框架如下: 



         mov cx,循环次数

标号: 代码段

...

        loop  标号


5.4  Debug和汇编编译器masm对指令的不同处理

1.在汇编语言中,如果一个指令要访问内存单元,则在指令中必须用[...]来表示内存单元,如果在[...]中直接用常量给出内存地址的偏移地址,那么需要在"[ ]"前面加上段寄存器。比如

mov al,ds:[0]如果没有显示的给出段寄存器ds:,那么mov al,[0]在汇编语言中被理解为mov al,0

2.在汇编语言中,也可以将偏移地址存入一个普通寄存器bx,比如

mov bx,0

mov al,[bx]这样也是允许的,其中段寄存器默认在ds中


5.5  段前缀

指令“mov ax,[bx]”中,内存单元的偏移地址由bx给出,而段地址默认在ds中。我们可以在访问内存单元的指令中显式地给出内存单元的段地址所在的段寄存器。比如:

(1)mov ax,ds:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在ds中。
(2)mov ax,cs:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在CS中。
(3)mov ax,ss:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在ss中。
(4)mov ax,es:[bx]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址在bx中,段地址在es中。
(5)mov ax,ss:[0]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为0,段地址在ss中。
(6)mov ax,cs:[0]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节(字单元),存放一个字,偏移地址为0,段地址在cs中。
这些出现在访问内存单元的指令中,用于显式地指明内存单元的段地址的“ds:”、“cs:”、“ss:”或“es:”,在汇编语言中称为段前缀。 


5.6 一段安全的空间

在一般的PC机中,DOS方式下,DOS和其他合法的程序一般都不会使用0:200~0:300(00200h~00300h)的256个字节的空间。所以,我们使用这段空间是安全的。不过为了谨慎起见,在进入DOS后,我们可以先用Debug查看一下,如果0:200-0:300单元的内容都是0的话,则证明DOS和其他合法的程序没有使用这里。

注意:我们在纯DOS方式(实模式)下,可以不理会DOS,直接用汇编语言去操作真实的硬件,因为运行在CPU实模式下的DOS,没有能力对硬件系统进行全面、严格地管理。但在Windows2000、UNIX这些运行于CPU保护模式下的操作系统中,不理会操作系统,用汇编语言去操作真实的硬件,是跟本不可能的。硬件已被这些操作系统利用CPU保护模式所提供的功能全面而严格地管理了。



5.8段前缀的使用

问题,我们需要将内存ffff:0~ffff:b单元的数据复制到0:200~0:20b

分析如下:

1.0:200~0:20b等同于 0020:0~0020:b,这样描述为了使得目标地址和源地址偏移量都从0开始

2.复制过程用loop循环实现

3.源段和目标段距离超过了64kb,所以用需要两次给段赋值或者用两个寄存器分别赋值实现。

assume cs:code
code segment
        mov ax,0ffffh
        mov ds,ax    ;ds段寄存器赋值为0ffffh

        mov ax,0020h
        mov es,ax    ;es辅助段寄存器赋值为0020h

        mov bx,0    ;此时ds:bx指向ffff:0,es:bx指向0020:0
        mov cx,12    ;计数寄存器cx赋值为12,循环12次
s:      mov dl,[bx]    ;将ffff:bx中的数据送入dl
        mov es:[bx],d1    ;将dl的数据(上一步中段地址为0ffffh,偏移地址为bx的数据)送入0020:bx
        inc bx    ;已循环次数+1   inc比add节省一个操作数
        loops       ;循环结束
            mov ax,4c00h    ;第4c个子程序,返回值al为0
            int 21h    21号中断
code ends
end



版权声明:若无特殊注明,本文皆为《 8964CN 》原创,转载请保留文章出处。
本文链接:[汇编语言] [bx]和 loop指令学习笔记 http://www.8964cn.net/?post=27
正文到此结束

热门推荐

发表吐槽

你肿么看?

你还可以输入 250 / 250 个字

嘻嘻 大笑 可怜 吃惊 害羞 调皮 鄙视 示爱 大哭 开心 偷笑 嘘 奸笑 委屈 抱抱 愤怒 思考 日了狗 胜利 不高兴 阴险 乖 酷 滑稽

评论信息框

吃奶的力气提交吐槽中...


既然没有吐槽,那就赶紧抢沙发吧!