Loading [MathJax]/jax/input/TeX/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Win32汇编:字符串操作指令

Win32汇编:字符串操作指令

作者头像
王 瑞
发布于 2022-12-28 06:53:14
发布于 2022-12-28 06:53:14
34900
代码可运行
举报
运行总次数:0
代码可运行

移动串指令: MOVSB、MOVSW、MOVSD ;从 ESI -> EDI; 执行后, ESI 与 EDI 的地址移动相应的单位 比较串指令: CMPSB、CMPSW、CMPSD ;比较 ESI、EDI; 执行后, ESI 与 EDI 的地址移动相应的单位 扫描串指令: SCASB、SCASW、SCASD ;依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化 储存串指令: STOSB、STOSW、STOSD ;将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化 载入串指令: LODSB、LODSW、LODSD ;将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化 其中的 B、W、D 分别指 Byte、Word、DWord, 表示每次操作的数据的大小单位.

上述指令可以有重复前缀: REP ECX > 0 时 REPE (或 REPZ) ECX > 0 且 ZF=1 时 REPNE(或 REPNZ) ECX > 0 且 ZF=0 时 ;重复前缀可以自动按单位(1、2、4)递减 ECX

字符串复制(movsb):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	string1 db "hello lyshark",0      ; 原始字符串
	str_len equ $ - string1 -1        ; 计算出原始字符串长度
	string2 db str_len dup(?),0       ; 目标内存地址

.code
	main PROC
		cld                       ; 清除方向标志
		mov esi,offset string1    ; 取源字符串内存地址
		mov edi,offset string2    ; 取目标字符串内存地址
		mov ecx,str_len           ; 指定循环次数,为原字符串长度
		rep movsb                 ; 逐字节复制,直到ecx=0为止
		ret
	main ENDP
END main

另一种字串复制(movsb): 不使用rep重复前缀的方式完成字串复制.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	string1 db "hello lyshark",0      ; 原始字符串
	str_len equ $ - string1 -1        ; 计算出原始字符串长度
	string2 db str_len dup(?),0       ; 目标内存地址

.code
	main PROC
		lea esi,string1               ; 取string1的地址
		lea edi,string2               ; 取string2的地址
		mov ecx,str_len               ; 取字符串长度,用于循环
		cld                       ; 方向->正向
	@@:	movsb                     ; 每次复制一个字节BYTE
		dec ecx                   ; 每次ecx减一
		jnz @B                    ; 如果ecx不为0则循环
		ret
	main ENDP
END main

(movsd)四字节复制字串:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	ddSource DWORD 10h,20h,30h               ; 定义三个四字节数据
	ddDest   DWORD lengthof ddSource dup(?)  ; 得到目标地址

.code
	main PROC
		lea esi,ddSource
		lea edi,ddDest
		mov ecx,lengthof ddSource
		cld
		rep movsd
		ret
	main ENDP
END main

CMPSB:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	Text1 db "hello lyshark",0
	Text2 db "hello lyshar1",0
.code
	main PROC
		lea esi,Text1
		lea edi,Text2
		mov ecx,lengthof Text1
		cld
		repe cmpsb
		je L1
		xor eax,eax            ; 字串不同则清空eax
		jmp L2
	L1:	xor ebx,ebx            ; 字串相同则清空ebx
	L2:	ret
	main ENDP
END main

CMPSD: 比对两个双字数据是否相等.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	var1 DWORD 1234h
	var2 DWORD 5678h
.code
	main PROC
		lea esi,var1
		lea edi,var2
		cmpsd
		je L1
		xor eax,eax      ; 两数如果相等则清空eax
		jmp L2
	L1:	xor ebx,ebx      ; 两数不相等则清空ebx
	L2:	ret
	main ENDP
END main

CMPSW:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	Array1 WORD 1,2,3,4,5      ; 必须全部相等才会清空ebx
	Array2 WORD 1,3,5,7,9
.code
	main PROC
		lea esi,Array1
		lea edi,Array2
		mov ecx,lengthof Array1
		
		cld
		repe cmpsw
		je L1
		xor eax,eax        ; 两数不相等则清空eax
		jmp L2
	L1:	xor ebx,ebx        ; 两数相等则清空ebx
	L2:	ret
	main ENDP
END main

SCASB 扫描字串: 依据 AL/AX/EAX 中的数据扫描 EDI 指向的数据, 执行后 EDI 自动变化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	szText BYTE "ABCDEFGHIJK",0
.code
	main PROC
	
		lea edi,szText
		mov al,"F"
		mov ecx,lengthof szText -1
		cld
		repne scasb                 ; 如果不相等则重复
		je L1
		xor eax,eax                 ; 如果没找到F则清空eax
		jmp L2
	L1:	sub ecx,lengthof szText -1
		neg ecx           ; 如果找得到, 这里显示是第几个字符; 本例结果是 6
	L2:	ret
	main ENDP
END main

STOSB 存储字串: 将 AL/AX/EAX 中的数据储存到 EDI 给出的地址, 执行后 EDI 自动变化

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	len = 10
	szText db len dup(0),0
.code
	main PROC
		lea edi,szText                   ; EDI指向字符串
		mov al,"W"                       ; 定义查找字母为W
		mov ecx,len                      ; 设置查找计数器
		cld                              ; 方向=正向
		rep stosb                        ; ecx>0则执行
		ret
	main ENDP
END main

LODSW 载入指令: 将 ESI 指向的数据载入到 AL/AX/EAX, 执行后 ESI 自动变化,如下是累加求和

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	Array WORD 1,2,3,4,5,6,7,8,9,10
.code
	main PROC
		lea esi,Array
		mov ecx,lengthof Array
		xor edx,edx
		xor eax,eax
	@@:	lodsw
		add edx,eax
		loop @B
		
		mov eax,edx           ; 最后将相加结果放入eax

	main ENDP
END main

初始化内存: 把String字符串中的,每一个字节均填充初始化为0FFh

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	Count = 100                 ; 申请空间为100
	String BYTE Count DUP(?)    ; 初始化为BYTE
.code
	main PROC
		mov al,0FFh             ; 指定要填充的数据为0FFh
		mov edi,offset String   ; EDI寄存器指向目标内存
		mov ecx,Count           ; 循环计数
		cld                     ; 初始化:方向=前方
		rep stosb               ;AL中的值进行填充
		ret
	main ENDP
END main

数组的乘法: 把双字数组中的每一个元素分别乘以一个常量,程序中使用了(LODSD加载),(STOSD保存).

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	Array DWORD 1,2,3,4,5
	Multi DWORD 10
.code
	main PROC
		mov esi,offset Array     ; 源指针
		mov edi,esi              ; 目的指针
		
		cld                      ; 方向=向前
		mov ecx,lengthof Array   ; 循环计数器
	L1:	lodsd                    ; 加载[esi]EAX
		mul Multi                ;EAX乘以10
		stosd                    ; 将结果从EAX存储至[EDI]
		loop L1
		ret
	main ENDP
END main

计算字符串长度: 以下代码用于计算字符串的长度,并将结果保存在EAX寄存器中.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	String BYTE "hello world",0      ; 带计算字符串
.code
	main PROC
		mov edi,offset String    ; 取出字符串的基地址
		xor eax,eax              ; 清空eax用作计数器
		
	L1:	cmp byte ptr [edi],0     ; 分别那[edi]的值和0作比较
		je L2                    ; 上一步为零则跳转得到ret
		inc edi                  ; 否则继续执行
		inc eax
		jmp L1
	L2:	ret
	
	main ENDP
END main

小写字串转大写: 将MyString变量中的小写字符串,依次转换为大写字符串.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	MyString db "hello lyshark",0      ; 定义MyString字符串

.code
	main PROC
		mov esi,offset MyString        ; 取出字符串的偏移地址
	L1:	cmp byte ptr [esi],0           ; 分别拿出每一个字节,0比较
		je L2                          ; 如果相等则跳转到L2
		and byte ptr [esi],11011111b   ; 执行按位与操作
		inc esi                        ; 每次esi指针递增1
		jmp L1                         ; 重复循环
	L2:	ret
	main ENDP
END main

定义二维数组: 定义一个二维数组Table,并取出第一行中的第2偏移地址的元素.

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.data
	Table WORD 10h,20h,30h,40h,50h    ; 定义一个数组
	Row = ($ - Table)                 ; 取出数组每行的字节数
	      WORD 60h,70h,80h,90h,0Ah    ; 继续定义数组
.code
	main PROC
		row_index = 1                 ; 表的偏移地址
		column_index = 2              ; 行的偏移地址
		
		mov ebx,offset Table          ; 取偏移地址给ebx
		add ebx,Row*row_index         ; 每行元素*偏移
		
		mov esi,column_index          ; 将行偏移赋值给esi
		mov ax,[ebx+esi*TYPE Table]   ; Table比例因子只能是2,4,8
	main ENDP
END main
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2019-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Oracle 表空间与数据文件
SYSAUX --->10g 高并发系统繁忙时,会造成system争用,将工具放到SYSAUX,减轻system的压力,SYSAUX不影响系统(影响性能)
Leshami
2018/08/07
1.4K0
案例|RAC 添加表空间误将数据文件放本地处理办法
不管是 10g、11g、12c ,RAC 架构的数据文件均是存放在共享存储上的,但是由于扩容时误操作少写一个符号,则会将数据文件建立到本地文件系统上的 $ORACLE_HOME/dbs 目录下,这样当然不会立即出错,也提示添加成功,但当另外一个节点访问此数据文件上面的数据时就会报错 ORA-1157、ORA-1110 提示无法锁定该数据文件,导致出现异常应用无法访问此数据。
JiekeXu之路
2020/11/17
6400
案例|RAC 添加表空间误将数据文件放本地处理办法
在 Oracle 归档模式下直接 rm dbf 数据文件并重启数据库还有救吗?
在 Oracle 归档模式下直接 rm data.dbf 数据文件并重启数据库还有救吗?为何会有这样的问题,要追溯到上周一位朋友咨询的事情,他那里一个 Oracle 单机的环境因为表空间不足了,需要扩容表空间,则通过添加表空间数据文件的命令加入了一个数据文件,执行成功后呢便可以继续写入数据了。
JiekeXu之路
2023/11/01
4660
在 Oracle 归档模式下直接 rm dbf 数据文件并重启数据库还有救吗?
SYSTEM 表空间管理及备份恢复
SYSTEM表空间是Oracle数据库最重要的一个表空间,存放了一些DDL语言产生的信息以及PL/SQL包、视图、函数、过程等,称之为数据字典,
Leshami
2018/08/07
1.1K0
SYSAUX表空间管理及恢复
SYSAUX表空间是在10g之后引入的一个新的表空间,主要用于减轻对SYSTEM表空间的压力而作为SYSTEM表空间的辅助表空间。
Leshami
2018/08/07
1.1K0
oracle迁移数据文件再也不用求人了
N 多年前安装的 oracle 数据库,巡检的时候发现磁盘满了,检查发现是数据文件占用了很大的空间,当前存放数据文件的磁盘不能再进行扩容,于是准备把业务数据文件迁移到其他磁盘分区
用户5921339
2025/05/20
1400
oracle迁移数据文件再也不用求人了
Oracle表空间和数据文件管理
在Oracle数据库中,表空间与数据文件之间的关系非常密切,这二者相互依存,也就是说,创建表空间时必须创建数据文件,增加表空间时也必须指定表空间;
星哥玩云
2022/08/16
6390
Oracle表空间和数据文件管理
Oracle表空间检测异常的问题诊断
不知道大家在工作中的表空间管理情况如何,大体会分为两派。以前的公司我们更喜欢直接把空间都分配好,比如500G的容量规划,那就提前准备500G,另外一类是我先给定200G,后续的空间就自动增长,反正容量还是500G。这个其实很大程度上就是个人习惯和公司流程规范的差别了。 为什么这么说呢,因为我在一套环境上收到了一个奇怪的报警。 DBA: IP: xxxx Tablespace: PERFSTAT: 122.5% [Critical!!] 关键就在这
jeanron100
2018/03/21
1.2K0
Oracle 表空间管理
33.12. Oracle 表空间 33.12.1. 查询空闲表空间 select tablespace_name,file_id,block_id,bytes,blocks from dba_free_space; SQL> select file_name from dba_data_files; FILE_NAME -----------------------------------------------------------------------------------------
netkiller old
2018/03/05
1.4K0
追本溯源:Oracle 只读表空间的探索实践
作者简介 胡中豪 云和恩墨西区交付工程师,多年一线 DBA 经验,曾服务于运营商、电网、政府行业、银行等行业客户;擅长数据库故障处理、性能优化、实施升级 本文由恩墨大讲堂147期线上分享整理而成。课程
数据和云
2018/03/05
2.3K0
追本溯源:Oracle 只读表空间的探索实践
ORACLE修改数据文件路径(四种方式)--转
移动数据文件/home/oracle/cjctbs02.dbf到/u01/app/oracle11/oradata/chendb/cjctbs02.dbf
Lucifer三思而后行
2021/08/17
3.4K0
ORACLE修改数据文件路径(四种方式)--转
表空间创建管理及控制文件管理
表空间是一个逻辑概念,物理上对应一个或多个数据文件 datafile 或临时文件 tempfiles,逻辑上表空间是存储段的容器。(段也是逻辑概念,是数据库中的对象如表、索引等)
用户8006012
2022/07/02
6500
Oracle 表空间详解
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
suveng
2019/09/18
3K0
Oracle 表空间详解
Oracle 11g 临时表空间管理
近期我们运维的数据库有几台出现了 temp 临时表空间使用率过高告警的问题,发现有些 DBA 竟然选择直接添加数据文件或者直接 resize 30G 来消除告警。这样导致临时文件很大占用很多磁盘空间,没有想到优化管理它,临时表空间过大只有重启实例使用率才会下降,如果没有临时表空间实例重启也会自动创建出来,那么今天抽出点时间来说说临时表空间的管理。
JiekeXu之路
2020/10/30
2.5K0
Oracle 11g 临时表空间管理
ORACLE数据文件名导致的奇怪问题 (51天)
今天创建了一些表空间,准备做data guard来看看效果。 为了方便起见,我用gridcontrol来做,主库也开了Omf,省去了好多步骤。 一路点下来,就等gc的那个状态变成对号了,结果装了近20分钟,alert日志开始报错。 ******************** WARNING *************************** The errors during Server autobackup are not fatal, as it is attempted after sucess
jeanron100
2018/03/13
1K0
Oracle表空间自动监控 自动扩容程序 修正版
答: 用这套自动扩容脚本就好(我已多年不Coding,下午写的这套代码比较Low,仅抛砖引玉,各位大神可在此基础上改写以便更好地适应自己的DB环境)
杨漆
2021/07/25
7440
Oracle表空间自动监控 自动扩容程序 修正版
只读表空间的备份与恢复
--====================== --  只读表空间的备份与恢复 --====================== 一、只读表空间的特性     使用只读表空间避免对静态数据的频繁备份     当使用alter tablespace tbs read only时,数据文件会执行检查点进程(将所有脏缓冲区的内容写至磁盘),         当前的SCN号会被标注,同时存储了SCN的数据文件头部被冻结.控制文件内也会记录该数据文件的冻结信息。     可以清除只读表空间的对象 二、只读表空间的备份     一般情况下,只读表空间只需要进行一次备份,即当表空间状态发生改变时应立即进行备份     可以使用OS系统cp命令来备份或RMAN进行备份只读表空间     使用RMAN时建议启用备份优化选项         RMAN> CONFIGURE BACKUP OPTIMIZATION ON;     只读表空间不支持热备     SQL> alter tablespace tbs1 begin backup;     alter tablespace tbs1 begin backup     *     ERROR at line 1:     ORA-01642: begin backup not needed for read only tablespace 'TBS1' 三、只读表空间的还原与恢复     还原与恢复只读表空间的问题在于控制文件如何控制只读表空间,分为下列三种情况:         ---------  ---------------  ----------------  -------------------------------------     case           backup 1     crash status                   recovery     ---------  ---------------  ----------------  -------------------------------------     case 1        Read-Only        Read-Only      将备份的只读表空间复制到目的地(Restore)     case 2        Read-Only        Read-Write     先Restore backup1,后recover(applied log )     case 3        Read-Write       Read-only       先Restore backup1,后recover(applied log )     只读表空间恢复时需要考虑的问题         重建一个控制文件时         重命名数据文件时         使用一个备份的控制文件时     下面对表空间tbs1置为只读后对比前后生成的重建控制文件的脚本       
Leshami
2018/08/07
6700
[Oracle 数据库日常操作] 表空间的日常运维命令
这个专题主要是一些日常运维中需要用到的命令,不定期更新~~ 1.查询表空间使用率 select a.tablespace_name,a.bytes/1024/ 1024 "Sum MB",(a.bytes-b.bytes)/1024 /1024 "used MB",b.bytes/ 1024/1024 "free MB",round(((a.bytes-b.bytes)/a.bytes)*100 ,2 ) "percent_used" from (select tablespace_name, sum(
bsbforever
2020/08/19
9620
临时表空间的管理与受损恢复
      Oracle 临时表空间是Oracle数据库的重要组成部分,尽管该部分并没有cont体系结构上得以展现,但其重要地位也是不容忽视的。尤其是 对于大型的频繁操作,如创建索引,排序等等都需要在临时表空间完成来减少内存的开销。当然对于查询性能要求较高的应尽可能的避免在磁盘 上完成这些操作。本文主要描述的是临时表空间的管理与受损恢复。
Leshami
2018/08/07
7780
oracle表空间操作
1,查询表空间剩余 -- 剩余量 select tablespace_name,sum(bytes) from dba_free_space group by tablespace_name; -- 总量 select tablespace_name,sum(bytes) from DBA_DATA_FILES group by tablespace_name; 2,查询数据库原始文件  select * from DBA_DATA_FILES; 3,增加表空间大小的四种方法 方法1:给表空间增加数据文件
大师级码师
2021/09/21
9850
推荐阅读
相关推荐
Oracle 表空间与数据文件
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验