posts - 422, comments - 576, trackbacks - 0, articles - 0

Assembly Loop

Posted on 2016-04-27 22:01 eryar 阅读(957) 评论(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的开始部分,而起始部分并不是指令,而是数据,从而导致程序直接运行时出现问题。为了解决这个问题,可以在指令起始的地方加个标号,这样就好了。


只有注册用户登录后才能发表评论。
【推荐】超50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理