Assembly Loop

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的开始部分,而起始部分并不是指令,而是数据,从而导致程序直接运行时出现问题。为了解决这个问题,可以在指令起始的地方加个标号,这样就好了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值