loop指令
loop指令是循环指令,对应的条件是cx中的值是否为0,如果不为0,loop指令会>.将cx的值减1,再跳到标号处执行,如果为0,则顺序执行下去,语法是 loop + 标号
例如 想执行8次
mov cx,8
s: 执行的指令集
loop s
[bx]指令访问内存
上一章中提到可以使用符号"[ ]"访问内存,里面可以加立即数,就是数字,也可以是使用寄存器间接寻址,使用寄存器间接寻址会在物理电路中实现,所以不是所有的寄存器都可以间接寻址,这里要说的寄存器是 bx 寄存器,它可以间接寻址,它默认的段地址是 ds 段地址。
含有多个段的汇编程序
一个汇编程序可以含有多个段,在上一节中我们只含有了代码段,但是还可以含有数据段,栈段,也可以含有两个数据段,两个代码段,自己定义的段
只含有一个段的程序
assume cs:code
code segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0ebah,0987h
dw 16 dup(0)
start:
mov ax,cs
mov ss,ax
mov sp,30h
mov bx,0
mov cx,8
s:push cs:[bx]
add bx,2
loop s
mov bx,0
mov cx,8
s0:pop cs:[bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0ebah,0987h
这条指令说明定义了8个字单元的内存个空间,里面依次存放着数据,从逻辑上,这里是存放数据的地方
dw 16 dup(0)
这句话的含义是申请一个16个字的内存空间,里面存放的数据都是0,从下文来看,mov sp,30h
是将这段内存看作是一个段了,30h(48)是自己计算出来的偏移地址。
dup(duplicate)是伪指令,含义是定义重复的数据,语法是 “数据类型 + 重复次数 + dup(重复的数据)”
start:
和end start
: 可以看到 dw的两行代码并不是指令,编译器并不会把它编译成正确的机器指令,而是会直接把数据当作机器指令,可以看如图:
所以所以我们要告诉编译器哪里是真正的要执行的代码,start是一个标号,而end start告诉编译器,真的开始的代码段是start开始的,那么指令就可以从start执行了。
这个程序最终达成的效果是数据逆序存放,关于指令loop等含义后面会解释。
含有多个段的程序
assume cs:code
data segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0ebah,0987h
data ends
stack segment
dw 16 dup(0)
stack ends
code segment
start:
mov ax,stack
mov ss,ax
mov sp,16
mov ax,data
mov ds,ax
mov bx,0
mov cx,8
s:push ds:[bx]
add bx,2
loop s
mov bx,0
mov cx,8
s0:pop ds:[bx]
add bx,2
loop s0
mov ax,4c00h
int 21h
code ends
end start
每个段通过segment和ends来表明,这个段的段地址就是段的标号,这样就可以使用多个段了
为什么使用多个段
(1)把它们放到一个段中使得程序显得混乱
(2)一个段的空间最大为64KB(8086中),也就是说我们的程序,包括数据代码和段的总和不能超过64KB,这显然是不行的。