【新书推荐】17.3 字符串操作举例

news2024/11/15 17:25:48

本节内容:字符串操作举例。

         ■例3:接收字符串去掉空格后逆向输出,t17-3.asm。

         ■例4:字符串拼接,t17-4.asm。

         ■例5:判断子串,t17-5.asm。

17.3.1 例3:接收字符串去掉空格后逆向输出

动手实验105写一个程序,先接收一个字符串,然后抽去其中的空格,最后按相反的顺序显示。

在理解下面示例程序的基础上,自己独立编写源程序。编译完成后,在debug调试器中单步跟踪调试,以验证程序的正确性。

算法分析:

第一步:DOS 10号功能接收字符串;

第二步:repz scasb过滤空格;

第三步:先入栈后出栈的方式逆向输出。

■流程图如图17-1所示。

图17-1 接收字符串去掉空格后逆向输出

示例代码81

;例3:写一个程序,先接收一个字符串,然后抽去其中的空格,最后按相反的顺序显示

;请注意删除空格的方法和方向标志的变化

;程序名:t17-3.asm

;功能:接收一个字符串,去掉其中的空格后按相反的顺序显示

;=========================================================

;符号常量的定义

maxlen=16       ;字符串最大长度

space=' '           ;空格

cr=0dh               ;回车符

lf=0ah                ;换行符

;数据段的定义

assume cs:code,ds:data

data segment

buffer db maxlen+1,0,maxlen+1 dup(0)

string db maxlen+3 dup(0)

data ends

code segment

start:

         mov ax,data

         mov ds,ax

         mov es,ax

         ;

         mov dx,offset buffer

         mov ah,10

         int 21h

         ;

         mov cl,buffer+1

         xor ch,ch

         jcxz ok

         ;

         cld

         mov si,offset buffer+2

         mov di,offset string

         ;预处结尾字符0

         mov al,0

         stosb        

         ;过滤空格

         mov al,space

pp1:

         jcxz pp3

         xchg si,di  ;si=string,di=buffer

         repz scasb

         xchg si,di  ;si=buffer,di=string

         dec si        ;scasb回退

         inc cx        ;repz回退

         ;

pp2:

         cmp byte ptr[si],space;si=buffer,di=string

         jz pp1

         movsb

         loop pp2

pp3: ;string存入回车换行              

         mov al,cr

         stosb

         mov al,lf

         mov [di],al       

         ;倒序显示                                                               

         std

         mov si,di

pp4:

         lodsb

         or al,al

         jz ok                                                                 

         mov dl,al

         mov ah,2

         int 21h

         jmp pp4

ok:

         mov ax,4c00h                                                         

         int 21h

code ends

end start

请注意上述示例中方向标志位的处理,以及删除空格字符的处理方法。

17.3.2 例4:字符串拼接

动手实验106写一个在字符串1后追加字符串2的程序,设字符串均以0结尾。

在理解下面示例程序的基础上,自己独立编写源程序。编译完成后,在debug调试器中单步跟踪调试,以验证程序的正确性。

算法分析:

第一步:将变址DI指针移到字符串1结尾;

第二步:计算字符串2的长度;

第三步:repz movsw指令将字符串2复制到字符串1结尾处;

注意奇数字节的处理movsb。

示例代码82

;例4:写一个在字符串1后追加字符串2的程序,设字符串均以0结尾

;程序名:t17-4.asm

;功能:字符串1后追加字符串2

;=========================================================

assume cs:code,ds:data

;符号常量的定义

maxlen=16       ;字符串最大长度

data segment

buffer1 db "1234",maxlen dup(0)

buffer2 db "56789",24h,0

data ends

code segment

start:

         mov ax,data

         mov ds,ax

         ;

         mov si,offset buffer1

         mov di,offset buffer2

         call strcat

         ;       

         mov dx,offset buffer1

         mov ah,9

         int 21h

         ;

         mov ax,4c00h

         int 21h

;-----------------------------------------------------

;写一个在字符串1后追加字符串2的子程序,设字符串均以0结尾

;说明:传送的字符串2包括结束标志,

;并从偶地址开始字传送(偶地址效率高,也可以直接传送),需要考虑可能遗留一个字节

;子程序名:strcat

;功能:在字符串1末尾追加字符串2

;入口参数:DS:SI=字符串1起始地址的段值:偏移

;DS:DI=字符串2起始地址的段值:偏移

;出口参数:无

;说明,不考虑字符串1后是否留有足够的空间

strcat proc

         push es

         push ax

         push cx

         push si

         push di

         cld

         push ds

         pop es                ;使ES同DS

         ;将si指针移到字符串1的结尾0处

         push di

         mov di,si            ;将字符串1作为目的串

         xor al,al

         mov cx,0ffffh

         repnz scasb      ;确定字符串1的尾 zf=1时

         lea si,[di-1]        ;si指向字符串1的结束标志

;测量字符串2的长度

         pop di

         mov cx,0ffffh

         repnz scasb      ;测量字符串2的长度

         not cx                ;CX包括结束标志字符串2的长度

         sub di,cx            ;DI再次指向字符串2的首

         ;将字符串2添加到字符串1结尾处

         xchg si,di           ;为拼接做准备

strcat1:

         shr cx,1           ;移动数据库长度除2

         repz movsw      ;字移动、ZF=0时结束

         jnc strcat2        ;进位标志CF=0

         movsb                ;补字移动遗留的一字节

strcat2:    ;

         pop di

         pop si

         pop cx

         pop ax

         pop es

         ret   

strcat endp

code ends

end start

上述示例先将指针移到字符串1的结尾处,然后将字符串2拷贝到字符串1的结尾处。注意,此代码实现为了提高拷贝效率,使用MOVSW指令,但需要考虑奇数个字节,最后一个奇数字节使用MOVSB指令。该示例对这一细节的处理有所冗余,请读者尝试优化代码。

17.3.3 例5:判断子串

动手实验107写一个判字符串2是否为字符串1的子串的程序,设字符串均以0结尾。

在理解下面示例程序的基础上,自己独立编写源程序。编译完成后,在debug调试器中单步跟踪调试,以验证程序的正确性。

算法分析:

第一步:分别测量字符串1和字符串2的长度;

第二步:双循环结构匹配字符串2和字符串1;

第三步:输出结果;

伪代码:参见示例代码47

流程图:如图17-2所示。

示例代码83

;例5:写一个判字符串2是否为字符串1的子串的程序,设字符串均以0结尾

;程序名:t17-5.asm

;功能:判字符串2是否为字符串1的子串

;=========================================================

assume cs:code,ds:data

data segment

string1 db "12345",0

string2 db "1234",0

result1  db "YES!",24H

result2  db "NO!",24H

data ends

code segment

start:

         mov ax,data

         mov ds,ax

         mov es,ax

         ;判断子串

         mov si,offset string1

         push ds

         push si

         mov di,offset string2

         push es

         push di

         call far ptr strstr

         ;输出结果

         or ax,ax

         jz NO

         mov dx,offset result1

         mov ah,9

         int 21h

         jmp OVER

NO: 

         mov dx,offset result2

         mov ah,9

         int 21h

         ;

OVER:

         mov ax,4c00h

         int 21h

;-----------------------------------------------------

;子程序名:strstr

;功能:判字符串2是否为字符串1的子串

;入口参数:指向字符串的远指针

;出口参数:DX:AX返回指向字符串2在字符串1中首次出现处的指针,AX=0不是子串

;说明:调用方法:

;压入字符串2的远指针

;压入字符串1的远指针

;call far ptr strstr

strstr proc far

         push bp

         mov bp,sp

         push ds

         push es

         push bx

         push cx

         push si

         push di

        

         les bx,[bp+6]                       ;取str2指针

         cmp byte ptr es:[bx],0      ;判断str2是否为空串

         jnz strstr1                  ;否

         jmp short strstr3

strstr1:

         cld

         les di,[bp+10]   ;取str1指针

         push es

         mov bx,di          ;str1偏移送bx寄存器

         xor ax,ax

         mov cx,0ffffh    ;测str1长度

         repnz scasb

         not cx

         mov dx,cx         ;dx=str1的长度(含结束标志)

        

         les di,[bp+6]     ;取str2指针

         push ds

         mov bp,di          ;str2偏移送bp寄存器

         xor ax,ax

         mov cx,0ffffh

         repnz scasb     ;测str2的长度

         not cx

         dec cx                ;cx=str2的长度(不含结尾0)

         pop ds                ;此时DS:BP指向str2

         pop es                ;ES:BX指向str1

        

         mov si,bp          ;DS:SI指向str2

         mov di,bx          ;ES:DI指向str1

         mov ax,cx         ;保存字符串2的长度

        

strstr2:

         mov cx,ax         ;cx=str2的长度(不含结尾0)

         mov di,bx          ;ES:DI指向str1

         repz cmpsb       ;在str1中搜索str2的字符  

         jcxz strstr4        ;是子串

         cmp byte ptr es:[di],0       ;str1结尾

         jz strstr3

         mov si,bp          ;不相同,DS:SI重新指向str2

         inc bx                 ;继续比对下一个字符

         jmp strstr2      

        

strstr3:

         xor ax,ax  ;不是子串

         jmp strstr5

strstr4:    

         mov ax,1

        

strstr5:

         pop di

         pop si

         pop cx

         pop bx

         pop es

         pop ds

         pop bp

         ret            

strstr endp

code ends

end start

         上述示例采用双循环结构,string2作为子串与string1进行比较。内循环将string2的每个字符与string1指定位置处的字符进行逐一比对。外循环从string1每个字符位置开始逐一与string2进行比对。

练习

1、请说明flag寄存器标志位DF的作用。如何设置DF?

2、 请写出与“LODSB”指令等价的程组合指令。

3、请写出与“STSOW”指令等价的组合指令。

4、请写出与“SCASB”指令等价的组合指令。

5、请写一个程序片段代替指令“REP MOVSW”。

6、请写一个片段代替指令“REPNZ CMPSB”。

7、请在debug调试器中观察重复前缀REP与重复前缀REPZ/REPE的机器码。

8、编写一个实现复制数据块的近过程。

9、编写一个实现字符串拷贝的近过程。堆栈传递作为参数的源和目标字符串首地址的偏移。

10、编写一个把字符串中的小写字母转换为大写(字符串以0结尾)的远过程。

11、改写例1和例2,通过堆栈传递入口参数。

12、编写一个把字符串2插入字符串1指定位置的远过程。

13、编写一个截取字符串某子串的近过程。

14、编写一个去掉字符串前导空格的近过程。

15、利用字符串操作指令写一个清屏的过程。只考虑字符显示方式。

本文摘自编程达人系列教材《X86汇编语言基础教程》。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1502949.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【正点原子STM32探索者】CubeMX+Keil开发环境搭建

文章目录 一、简单开箱二、资料下载三、环境搭建3.1 安装Keil MDK3.2 激活Keil MDK3.3 安装STM32CubeMX3.4 安装STM32F4系列MCU的Keil支持包 四、GPIO点灯4.1 查阅开发板原理图4.2 创建STM32CubeMX项目4.3 配置系统时钟和引脚功能4.4 生成Keil项目4.5 打开Keil项目4.6 编译Keil…

回收站选址(CCF 201912-2)解题思路

分析 把x,y坐标拼接成一个字符串(x,y)作为Set的key,保存到Set中,遍历Set,取出坐标,然后判断上下左右四个点是否在Set中,如果在,进而判断,四个角是否在Set中,…

git学习(创建项目提交代码)

目录 操作步骤如下 1.创建项目 2.初始化项目 3.初始化项目 4.创建一个文本文件将其推送到远程仓库 5.添加到暂存区 查看提交状态 git push 返送到暂存区 git statues 7.提交 8. 返回远程仓库检查是否上传成功 操作步骤如下 git init //初始化git remote add origin ht…

《C缺陷和陷阱》-笔记(2)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 文章目录 前言 一、理解函数声明 1.(*(void(*)( ))0)( ); 2.signal 函数接受两个参数: 3.使用typedef 简化函数声明: 二、运算符的优先级…

uniapp踩坑之项目:uni.previewImage简易版预览单图片

主要使用uni.previewImage //html <view class"box-card" v-for"(item,index) in DataList" :key"index"><view>图片&#xff1a;</view><image :src"item.Path" tap.stop"clickImg(item.Path)">&l…

如何深度学习

信息爆炸时代&#xff0c;诞生了很多新的学习方式&#xff0c;非常轻松就能掌握知识&#xff0c;比如&#xff0c;每天听一本书&#xff0c;半个小时就能学习一本书的精华&#xff0c;比如订阅名家专栏或者课程&#xff0c;在不长的时间内内就能学到很多知识。 很多人认为这样…

HTML5页面布局

1,图文混排布局 img {float: right;}p {font-size: 32px;} <div class"sec"><img src"penguin.png" alt"penguin"><p>With no change in the rule, the more you grow the more envious you be123 123132312...</p> &l…

安全测试工具Burpsuit和OWASP ZAP使用入门指南

Burpsuit使用入门指南 安装&#xff1a; 网上有很多相关相关保姆级别教程&#xff0c;所以这里不加赘述了尽量使用java8版本&#xff0c;破解版兼容8做的比较好如果发现注册机无法打开或者能打开注册机【run】无法点击唤起软件安装&#xff0c;可以使用命令行工具 java -jar …

JavaScript 实现飞机大战

文章目录 一些关键点概览&#xff1a;核心模块的具体实现示例&#xff1a;飞机类&#xff08;Plane&#xff09;的基本结构&#xff1a;子弹类&#xff08;Bullet&#xff09;的基本结构&#xff1a;敌机类&#xff08;Enemy&#xff09;的基本结构&#xff1a; 基于前面定义的…

膜厚测量仪在半导体应用中及其重要

随着科技的不断发展&#xff0c;半导体行业已成为当今世界的核心产业之一。在这个领域中&#xff0c;半导体膜厚测量仪作为关键设备&#xff0c;其精度和可靠性对于产品质量和生产效率具有至关重要的作用。本文将详细介绍半导体膜厚测量仪的工作原理、应用领域以及其在半导体制…

SpringMVC04、Controller 及 RestFul

4、Controller 及 RestFul 4.1、控制器Controller 控制器复杂提供访问应用程序的行为&#xff0c;通常通过接口定义或注解定义两种方法实现。控制器负责解析用户的请求并将其转换为一个模型。在Spring MVC中一个控制器类可以包含多个方法在Spring MVC中&#xff0c;对于Contr…

GSM8K数据集分享

来源: AINLPer公众号&#xff08;每日干货分享&#xff01;&#xff01;&#xff09; 编辑: ShuYini 校稿: ShuYini 时间: 2024-3-3 先进的语言模型可以在许多任务上与人类表现相媲美&#xff0c;但它们仍然难以执行多步骤数学推理任务。为此OpenAI团队创建了一个高质量、语言多…

Midjourney绘图欣赏系列(八)

Midjourney介绍 Midjourney 是生成式人工智能的一个很好的例子&#xff0c;它根据文本提示创建图像。它与 Dall-E 和 Stable Diffusion 一起成为最流行的 AI 艺术创作工具之一。与竞争对手不同&#xff0c;Midjourney 是自筹资金且闭源的&#xff0c;因此确切了解其幕后内容尚不…

如何通过四维轻云SDK开发打造智慧景区管理平台?

智慧景区管理平台通常是基于GIS技术&#xff0c;在三维实景地图的基础上&#xff0c;接入景区各类传感设备、第三方系统数据&#xff0c;进行业务功能的梳理及开发。但对于没有GIS开发经验的团队而言&#xff0c;地图开发具有一定的技术门槛&#xff0c;尤其是需要在前端解决好…

使用Revman绘制森林图教程

一 打开Revman 软件 mac 版打开界面如下&#xff0c;叉掉 welcome 点击左上角新文件图标 next——》 填写标题 第一项是针对什么健康问题的什么研究 第二项是什么和什么针对什么问题的比较研究 第三项是针对什么专题的什么健康问题的什么研究 第四项是自定义标…

Java 的 System 类常用方法介绍

Java 中的 System 类是一个final类&#xff0c;它提供了与系统相关的属性和方法。它是一个内置的类&#xff0c;可以直接使用&#xff0c;不需要实例化。System 类提供了标准输入、标准输出和错误输出流&#xff0c;以及对外部定义的属性和系统环境的访问。下面是 System 类的一…

C.C语言分支和循环语句

文章目录 一. 什么是语句 二. 分支语句&#xff08;选择结构&#xff09; 2.1. if 语句 2.1.1. 语法结构 2.1.2. 悬空else 2.1.3. 书写形式的对比 2.1.4. 练习 2.2. switch 语句 3.2.1. 语法结构 3.2.2. 在switch语句中的 break 3.2.3. default子句 3.2.4. 练习 三…

电动机工作原理图

电机&#xff08;俗称“马达”&#xff09;是指依据电磁感应定律实现电能转换或传递的一种电磁装置。它的主要作用是产生驱动转矩&#xff0c;作为用电器或各种机械的动力源。 电动机&#xff0c;转子置于旋转磁场中&#xff0c;在旋转磁场的作用下&#xff0c;获得一个转动力…

本金1w+能做好电商吗?可以做什么平台?

我是电商珠珠 有的小伙伴想要做电商&#xff0c;但是害怕风险太高。眼看着别人的店铺都做起来了&#xff0c;自己还不知道选哪个平台入驻。自己准备1w的本金&#xff0c;也不了解各个平台的入驻机制是怎么样的&#xff0c;什么平台更适合像自己一样的新手小白。 我做电商已经…

苹果cms模板保护设置,防止被扒

苹果cms模板保护设置&#xff0c;防止被扒 如今互联网时代&#xff0c;网站模板前端被扒是常有的事&#xff0c;如何防止模板数据被扒&#xff1f; 保护设置方法&#xff1a; 登录宝塔 找到安装模板的网站 设置禁止访问文件 方法参考截图后缀填&#xff1a;php|html 目录填&a…