Assembly Loop

简介: Assembly Loop eryar@163.com 我觉得循环指令是程序的核心,是计算机不厌其烦地执行机械、重复枯燥劳动的基础。本文来学习下汇编程序中的LOOP指令。Loop指令的格式是:loop 标号,CPU执行loop指令的时候,要进行两步操作: v (cx)=(cx)-1 v 判断cx中的值,不为零则转到标号处执行程序,如果为零则向下执行。

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

目录
相关文章
|
Go API
一文搞懂Go读写Excel文件
一文搞懂Go读写Excel文件
295 0
|
开发工具 git
Git从远程仓库拉取指定的分支
Git从远程仓库拉取指定的分支
2752 0
Unknown encoder ‘libx264‘的解决方法
Unknown encoder ‘libx264‘的解决方法
1824 0
|
机器学习/深度学习 数据采集 算法
数据挖掘和机器学习算法
数据挖掘和机器学习算法
|
安全 Linux 数据处理
Linux命令shred详解:数据安全删除的艺术
`shred`是Linux下用于安全删除文件的命令,它通过多次随机覆盖确保数据无法恢复。工作原理包括默认三次的覆盖,用户可自定义次数。主要特点有:多次覆盖、可定制、灵活操作和安全删除。示例:`shred -n 5 -z -v -u file.txt`(覆盖5次,填充0,删除文件)。使用时注意确认文件、备份数据、检查权限和文件系统兼容性。最佳实践是结合`rm`使用,根据敏感度选择覆盖次数。
uniCloud + uView 上传图片,删除图片(含u-upload 组件的使用)
uniCloud + uView 上传图片,删除图片(含u-upload 组件的使用)
590 0
|
消息中间件 Java Apache
使用Spring Boot实现与ActiveMQ的消息队列集成
使用Spring Boot实现与ActiveMQ的消息队列集成
|
SQL 数据库 数据安全/隐私保护
harbor修改密码
在Harbor `v2.9.0`中,忘记密码可使用以下方法强制重置:通过`docker exec`进入harbor-db容器,使用SQL命令`update harbor_user set salt='',password='' where user_id = 1;`清空admin密码。然后重启Harbor,系统将要求初始化新密码。注意此操作涉及数据库交互,需谨慎执行。
1266 0
|
存储 固态存储 Java
multi-stream SSD 介绍
# NVMe Multi-stream ## 1. 原理介绍 ### 1.1. flash 写操作 在介绍 multi-stream 之前,首先简单介绍一下 flash 写操作的特性。 - SSD 中写操作(write)的单元为 page,page 的大小通常为 2 ~ 64 KB - NAND flash 在对 page 写操作之前,必须对 page 执行擦除操作(er
9251 0
|
人工智能 iOS开发 MacOS
菜鸟打印组件系列-vue3快速接入
本文一开始介绍了菜鸟打印组件,相关名词,以及在打印方面的相关能力和使用时的注意点。接着举例基于vue3+pina+elementPlus的项目通过步骤1.使用pina 创建websoket相关处理的模块,处理打印机与浏览器长连接的过程。步骤2.按照菜鸟要求的模板语言,调整自己的打印模板,并且放在public文件夹下,步骤3.在列表页其中使用el-table组件,引入websoket模块,连接菜鸟组件以及批量打印,实现简单的批量打印功能
1200 0
菜鸟打印组件系列-vue3快速接入