聚合国内IT技术精华文章,分享IT技术精华,帮助IT从业人士成长

Assembly Loop

2016-04-28 10:20 浏览: 1766552 次 我要评论(0 条) 字号:

Assembly Loop

eryar@163.com

我觉得循环指令是程序的核心,是计算机不厌其烦地执行机械、重复枯燥劳动的基础。本文来学习下汇编程序中的LOOP指令。Loop指令的格式是:loop 标号,CPU执行loop指令的时候,要进行两步操作:

v (cx)=(cx)-1

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

由上可知,cx中的值影响着loop指令的执行结果。通常我们用loop指令来实现循环功能,用cx来存放循环次数。类似于C中的for循环:

for (int i = cx; i != 0--i) 


学习了loop后,想着把原来那个输出WELCOME TO ASM!的程序修改下,利用循环来实现。

 

assume cs:codeseg

codeseg segment
    ;WELCOME TO ASM
! (15)
    dw 0257h,0245h,034ch,0443h,054fh,064dh,0745h,0220h,0854h,094fh,0220h,1241h,1353h,144dh,1521h
    
    mov bx,0b800h
    mov ds,bx
    
    mov bx,
0
    mov cx,
15
    
    output:  mov ax,cs:[bx]
        mov ds:[bx],ax
        add bx,
2
        loop output
    
    mov ax,4c00h
    
int 21h
codeseg ends

end 


改成这样后,编译、连接成功,但是程序运行时好像进入了死循环。最后看书中的描述才找到了原因:那是因为用dw在代码段定义了数据后,当程序运行时IP指向的是数据部分,并不是指令部分,所以导致运行出错。使程序成功运行的方法有可以在debug中手动修改IP,使其指向真正的指令开始的地方,可是这样一来程序只能在debug中才能正确运行。如何让程序编译、连接后可以在系统中直接运行呢?我们可以在源码中指定程序的入口所在,即在源码的第一条指令的前面加上一个标号main,而这个标号在伪指令end的后面出现。因为我觉得这有点像C中的main函数,所以将这个标号命名为main,修改程序后程序运行正确:

 

assume cs:codeseg

codeseg segment
    ;WELCOME TO ASM
! (15)
    dw 0257h,0245h,034ch,0443h,054fh,064dh,0745h,0220h,0854h,094fh,0220h,1241h,1353h,144dh,1521h
    
    main: mov bx,0b800h
    mov ds,bx
    
    mov bx,
0
    mov cx,
15
    
    output:  mov ax,cs:[bx]
        mov ds:[bx],ax
        add bx,
2
        loop output
    
    mov ax,4c00h
    
int 21h
codeseg ends

end main

程序运行结果如下图所示:

wps_clip_image-38

综上所述,将数据放到代码段CS中时,会导致IP还是指向的CS的开始部分,而起始部分并不是指令,而是数据,从而导致程序直接运行时出现问题。为了解决这个问题,可以在指令起始的地方加个标号,这样就好了。



网友评论已有0条评论, 我也要评论

发表评论

*

* (保密)

Ctrl+Enter 快捷回复