MASM32+Visual 2010 编辑字符函数(strset、strcmp等)

MASM32+Visual 2010 编辑字符函数

一.实验目的
	利用MASM32+Visual 2010,利用汇编语言,写出如下字符函数:
	   (1)strset    (2)strlen   (3)strcmp
	   (4)strchr    (5)memset   (6)memcpy
二.环境配置
	参考:MASM32+Visual studio 2010写汇编程序入门
	连接:https://blog.csdn.net/MaxWoods/article/details/44649685?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160182254019725222408586%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=160182254019725222408586&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-1-44649685.pc_first_rank_v2_rank_v28&utm_term=MASM32%2bVisual%20studio%202010%E5%86%99%E6%B1%87%E7%BC%96%E7%A8%8B%E5%BA%8F&spm=1018.2118.3001.4187
三.MASM32入门
	假如学过微机原理,但是对 VS2010汇编编程不太熟悉的话,请参阅下文:
	[入门masm32编写简单汇编程序并做具体分析](https://blog.csdn.net/codes_first/article/details/78279641?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522160179651419724848341514%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fall.%2522%257D&request_id=160179651419724848341514&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v28-1-78279641.pc_first_rank_v2_rank_v28&utm_term=MASM32%E5%86%99%E6%B1%87%E7%BC%96%E7%A8%8B%E5%BA%8F%E5%85%A5%E9%97%A8&spm=1018.2118.3001.4187)
四.思路与代码详解
3.1.strset函数
(1)strset函数功能
	strset(string s,char c)——>将字符串s中所有的字符设置成c
(2)程序流图
	step1:设置指针指向需要改变的字符串
	step2:比较:此指针所指的字节值<——>0
	step3:如果不相等,将此指针所指的字节值变为字符c,更新指针
	step4:否则,更新指针,转到step2
(3)代码实现
.386
.model flat, stdcall

include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
szText	db	"Reverse Engineering", 0
chr		db	'j'

.code
main PROC
	LEA EDI, szText
	MOV ECX,0FFFFFFFFH
	XOR EAX,EAX                        ;将EAX置为0
	MOV AL,chr                         ;将低位AL置为j
	change:                           
		MOV [EDI],AL                   ;将j放入sztext中,将其中的一个字符变为J
		ADD EDI,1                      ;改变地址,使得地址增加
		CMP BYTE PTR [EDI],0           ;观察一下,看这个字符是不是为0
		JNZ change                     ;如果不是的话,就继续change循环
	
	INVOKE crt_printf, addr szText     ;将sztext打印出来
	INVOKE crt_getchar
	INVOKE ExitProcess, 0
main ENDP

END main
	注意:上述代码中:
	.386
	.model flat,stdcall
	include kernel32.inc
	includelib kernel32.lib
	...
	这些代码段,均是使用C++进行汇编的一般架构,在上述连接:入门masm32编
	写简单汇编程序并做具体分析中,有详细的叙述。
(4)结果展示
	将"Reverse Engineering"全部转为"jjjj...jjjjj"

在这里插入图片描述

3.2.strlen函数
(1)strlen函数功能
	int strset(string s)——>计算字符串s的长度
(2)程序流图
	step1:设置指针指向需要计算长度的字符串,设置记录长度的寄存器初始为0
	step2:比较:此指针所指的字节值<——>0
	step3:如果不为0,将记录长度的寄存器+1,更新指针
	step4:否则,说明字符串已经到结尾,结束程序
(3)代码实现
.386
.model flat, stdcall

include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
szText	db	"xie chuan long is shuai", 0
format	db	"length = %d", 0AH, 0

.code
main PROC
	LEA EDI, szText            ;将字符串的初始地址放到EDI中去
	MOV ECX,0FFFFFFFFH
	
	MOV EAX,0                  ;计数,初始值设为0
	 count:                    
		CMP BYTE PTR [EDI],0   ;比较[EDI]的值(字符串的某个字符)是否为\0
		PUSHFD                 ;将标志寄存器压入栈中
		ADD EDI,1              ;将地址位+1
		INC EAX                ;还没看出[EDI]是否为\0,先加上再说
		POPFD                  ;将标志寄存器出栈
     LOOPNZ count              ;观察ZF是否为0,如果不为0,循环count
	    DEC EAX                ;因为最后把\0也加上了,所以要减去1
	
	INVOKE crt_printf, addr format, EAX
	INVOKE crt_getchar
	INVOKE ExitProcess, 0
main ENDP

END main
(4)结果展示
	计算"xie chuan long is shuai"的长度=23

在这里插入图片描述

3.3.strcmp函数
(1)strcmp函数功能
	int strcmp(string s1,string s2):如果s1=s2,输出为0;如果s1>s2
	(s2更短,或s2对应字符的ASCII更小),输出为1;如果前两种情况都不是
	,输出为-1。
(2)程序流图

在这里插入图片描述

	注意:s1(i)的含义为:s1字符串的第i个字符
(3)代码实现
szText		db	"Reverse Engineering", 0
szText2		db	"Reverse Engineering", 0	;szText==szText2
szText3		db	"Reverse Eng", 0			;szText>szText3
szText4		db	"Reverse Engj", 0			;szText<szText4
szText5		db	"Reverse Engh", 0			;szText>szText5

.code
main PROC
	LEA ESI, szText
	LEA EDI, szText2	;result=0
	;LEA EDI, szText3	;result=1
	;LEA EDI, szText4	;result=-1
	;LEA EDI, szText5	;result=1
	
	
	;话不多说,都在图中
	compare:
		MOV BL,[EDI]
		CMP BYTE PTR [ESI],BL
		JNE noequal
	    CMP BYTE PTR [ESI],0
		JE  equal
		ADD ESI,1
		ADD EDI,1
	    JMP compare	
	    
	equal:
		MOV EAX,0
	JMP print	
	
	noequal:
		MOV BL,[EDI]
		CMP BYTE PTR [ESI],BL
		JA bigger
		
	smaller:
		MOV EAX,-1
		JMP print
		
    bigger:
		MOV EAX,1
		

    print:
		INVOKE crt_printf, addr format, EAX  ;EAX=result
		INVOKE crt_getchar
		INVOKE ExitProcess, 0
main ENDP

END main
(4)结果展示
	情况一:s1=szText	s2=szText2="Reverse Engineering"

在这里插入图片描述

	情况二:s1=szText	s2=szText3="Reverse Eng"
	       或者 s1=szText	s2=szText5="Reverse Engh"。输出相同结果。

在这里插入图片描述

	情况三:s1=szText	s2=szText4="Reverse Engj"

在这里插入图片描述

3.4.strchr函数
(1)strchr函数功能
	int strchr(string s,char d)——>找到字符d在字符串s中的位置
(2)程序流图

在这里插入图片描述

(3)代码实现
.386
.model flat, stdcall

include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
szText	db	"Reverse Engineering", 0
chr		db	'i'
format	db	"%d", 0AH, 0
result  db "The program is over",0

.code

main PROC
	LEA EDI, szText
	MOV ECX,0FFFFFFFFH

	MOV EBX,1                                  ;EBX记录现在在字符串的哪个位置


	equ0:
		MOV CL,chr                             ;将要寻找的字符给CL
		CMP BYTE PTR [EDI],0                   ;比较现在EDI所在的位置字符是否为0
		JE over                                ;如果为0,则程序结束
        CMP BYTE PTR [EDI],CL                  ;否则,比较EDI所在字符是否为要找的字符'i'
		JNE noprint                            ;如果不是,则直接开启下一个equ0循环

		INVOKE crt_printf, addr format,EBX     ;我们找到了'i'并输出,但是也许后面也有'i'!
		
		noprint:
			
			ADD EDI,1
			ADD EBX,1
		JMP equ0
	
	over:
		INVOKE crt_printf, addr result


	INVOKE crt_getchar
	INVOKE ExitProcess, 0
main ENDP

END main
(4)结果展示
	输出字符串"xie chuan  long,i love you"中'i'字符的位置:

在这里插入图片描述

3.5.memset函数
(1)memset函数功能
	void *memset(string s,char d,int size)——>将字符串s前size个字节用字符d替换
(2)程序流图
	这个程序逻辑很简单,与前面strlen类型相似,在此不做描述。代码中有注释。
(3)代码实现
.386
.model flat, stdcall

include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
szText	db	"xie chuan long is shuaige", 0
chr		db	'x'
siz     db  3
format	db	"%d", 0AH, 0


.code

main PROC
	LEA EDI,szText                 

	MOV ECX,0FFFFFFFFH

	XOR ECX,ECX              
	XOR EDX,EDX
	MOV DH,chr                               ;将要重复的字符chr->DH
    MOV CL,siz                               ;将要复制的长度siz->CL
	
	change:
		CMP CL,0                             ;比较CL是否为0,如果为0,则输出转换后的结果
		JE  print 
		MOV [EDI],DH                         ;将siz->EDI所处位置               
		ADD EDI,1                            ;更新EDI与CL
		DEC CL                        
		JMP change

     print:
	    INVOKE crt_printf, addr szText
		INVOKE crt_getchar
		INVOKE ExitProcess, 0
main ENDP

END main
(4)结果展示
	将字符串"xie chuan long is shuaige"前三个字符变为"x":

在这里插入图片描述

3.6.memcpy函数
(1)memcpy函数功能
	void *memcpy(void *destin, void *source, unsigned n)——>将source所指字节按顺序给destin,字节长度为n
(2)程序流图
	这个程序逻辑也很简单,在此不做描述。代码中有注释。
(3)代码实现
.386
.model flat, stdcall

include kernel32.inc
includelib kernel32.lib

include msvcrt.inc
includelib msvcrt.lib

.data
szText	db	"xie chuan long is shuaige", 0
chr		db	128 dup(0)
format	db	"%d", 0AH, 0

.code

main PROC
	LEA EDI,szText                 ;EDI指向要复制的字符串,ESI指向目的地址
	LEA ESI,chr
	MOV ECX,0FFFFFFFFH

	copy:
		CMP BYTE PTR [EDI],0       ;判断此时[EDI]是否为0
		JE print                   ;如果为0,说明字符串已经到末尾,应该结束了
  
		PUSH [EDI]                 ;[EDI]->[ESI]
		POP  [ESI]  
		ADD EDI,1                  ;将EDI与ESI增加1
		ADD ESI,1
	    JMP copy

	print:
		INVOKE crt_printf, addr chr
		INVOKE crt_getchar
		INVOKE ExitProcess, 0
main ENDP

END main
(4)结果展示

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值