ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

汇编语言[王爽]-05 [BX]和loop指令

汇编语言[王爽]-05 [BX]和loop指令

loop指令实现循环

执行过程:

①(cx)=(cx)-1

②判断 cx 中的值,不为零则转至标号处执行程序,如果为零则向下执行。

例:计算2^12

assume cs:codesegcodeseg segmentmov ax,2#-------做11次add ax,ax----------mov cx,11
s:add ax,axloop s#--------------------------------mov ax,4c00hint 21hcodeseg ends
end

框架

	mov cx,循环次数
s:循环的程序段loop s

考虑这么一个问题:计算ffff:0006单元中的数乘以3,结果储存在dx中

分析:

  1. 结果不能储存在一个8位的寄存器中,存在越界的可能,存在16位的寄存器中显然则不会越界,所以需要存在dx中而不是dl或者dh
  2. 基本思路:dx=0,把(ffff:0006)中的字节型数据放入ax中,执行三次add dx,ax
  3. 八位的内存单元如何给16位的ax赋值? 令(ah)=0,赋值给al
assume cs:code
code segmentmov ax,0ffffhmov ds,axmov bx,6hmov ah,0mov al,[bx]mov dx,0mov cx,3
s:add dx,axloop smov ax,4c00hint 21h
code ends
end

当写入 mov al,[dx] 时,编译器报错

Untitled

debug调试循环的方式

g ip地址 : 直接执行到某条指令

p : 可以用来结束int 21h,也可以用来跳过循环

注:debug调试程序时,文件名要带上后缀 -debug p.exe

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

mov ax,[0]

Debug解释为 mov ax,((ds)*16+0)

masm解释为 mov ax,0

所以在masm要写为

# 显示指明段前缀
mov ax,ds:[0]# 用寄存器
mov bx,0
mov ax,[bx]

loop 和 [bx]的联合运用

考虑这样一个问题,计算ffff:0 ~ ffff:b 单元中的数据的和,结果储存在bx中

8位数据存入al,以ax为中转赋值给bx【bx不会越界进位】

assume cs:code
code segmentmov ax,0ffffhmov ds,axmov bx,0	;初始化ds:bx指向ffff:0mov dx,0	;初始化累加器dx, (dx)=0mov cx,12	;初始化循环计数寄存器cx
s:mov ah,0mov al,ds:[bx]	;ax为中介传递数据add dx,axinc bx			;ds:bx指向下一个元素loop smov ax,4c00hint 21h
code ends
end

一段安全的空间

assume cs:code
code segmentmov ax,0mov ds,axmov ds:[26h],axmov ax,4c00hint 21h
code ends
end

执行上述的程序,系统会死机

因为在实模式下,我们可以自由地操纵真实的硬件;

在保护模式下,则是在操作系统的保护下,无法操纵真实的硬件

所以在实模式下编程时,要使用安全的内存空间

一般是 0:200 ~ 0:2ff 这256字节的空间

段前缀的使用

考虑一个问题,把内存ffff:0 ~ ffff:b中的数据复制到 0:200 ~ 0:20b中

assume cs:code
code segment;设置两个段前缀mov ax,0ffffhmov ds,axmov ax,20hmov es,axmov bx,0mov cx,12
s:mov dl,ds:[bx]mov es:[bx],dlinc bxloop smov ax,4c00hint 21h
code ends
end

为什么要使用 dl 而不是 mov es:[bx], ds:[bx]

因为 直接mov的话,没有指定内存大小,会报错

Untitled

其实可以用 dx 但是那样的话 bx就不是 inc 而是 add bx,2

实验四 [bx]和loop的使用

第四章 第一个程序

返回列表