首页 > 编程语言 >简单汇编教程9 字符串与字符串指令

简单汇编教程9 字符串与字符串指令

时间:2024-10-21 22:47:10浏览次数:3  
标签:汇编 教程 STRING mov PRINT 寄存器 字符串 MY

目录

字符串的指令

movs 字符串传送

lods, stos使用

cmpsb的使用

SCASB的使用


字符串你很熟悉了,我们定义了无数次了!

%macro ANNOUNCE_STRING 2
    %1 db %2
    %1_LEN equ $ - %1
%endmacro

当然,我们现在来学习一个比较新的定义方式,那就是跟C语言一样安插一个哨兵字符\0,它的ASCII值就是0

message DB 'I am loving it!', 0

后面我们会写一个函数叫做strlen函数!这里需要提示的就是我们的哨兵字符0会发挥最用!

字符串的指令

每个字符串指令可能需要一个源操作数,一个目标操作数或两者。对于32位段,字符串指令使用ESI和EDI寄存器分别指向源和目标操作数。但是,对于16位段,SI和DI寄存器分别用于指向源和目标。

有五个用于处理字符串的基本说明。他们是-

  • MOVS-该指令将1字节,字或双字数据从存储位置移到另一个位置。

  • LODS-该指令从存储器加载。如果操作数是一个字节,则将其加载到AL寄存器中;如果操作数是一个字,则将其加载到AX寄存器中,并将双字加载到EAX寄存器中。

  • STOS-该指令将数据从寄存器(AL,AX或EAX)存储到存储器。

  • CMPS-该指令比较内存中的两个数据项。数据可以是字节大小,字或双字。

  • SCAS-该指令将寄存器(AL,AX或EAX)的内容与内存中项目的内容进行比较。

上面的每个指令都有字节,字和双字版本,并且可以通过使用重复前缀来重复字符串指令。这些指令使用ES:DI和DS:SI对寄存器,其中DI和SI寄存器包含有效的偏移地址,这些地址指向存储在存储器中的字节。SI通常与DS(数据段)相关联,DI通常与ES(额外段)相关联。DS:SI(或ESI)和ES:DI(或EDI)寄存器分别指向源和目标操作数。假定源操作数位于内存中的DS:SI(或ESI),目标操作数位于ES:DI(或EDI)。

对于16位地址,使用SI和DI寄存器,对于32位地址,使用ESI和EDI寄存器。

基本指令操作的寄存器字节运算字运算双字运算
MOVSES:DI,DS:SIMOVSBMOVSWMOVSD
LODSDS:SILODSBLODSWLODSD
STOSES:DI,AXSTOSBSTOSSTOSD
CMPSDS:SI,ES:DICMPSBCMPSWCMPSD
SCASES:DI,AXSCASBSCASWSCASD

movs 字符串传送

这是字符串的传送指令,我的意思是:想要知道字符串如何传送,实际上需要ees, eds, edi, esi,ecx这几个寄存器。字符串的传送比较麻烦,因为你需要提供字符串的源地址(如果很长那还需要es, ds),以及传送的长度如何。

当然,传送长度就需要请出我们的ECX作为我们的Indexer了。下面我来露一手:

; --------------------------------------------------
;   Program written in 10.21 2024
;   Author:             Charlie chen
;   Functionality:      usage of movsb
; --------------------------------------------------
​
%macro ANNOUNCE_STRING 2
    %1 db %2
    %1_LEN equ $ - %1
%endmacro
​
; fast use of common value
%define MY_STDOUT       1
%define MY_SYS_WRITE    4
​
; print string in a simple way
%macro PRINT_STRING 2
    mov edx, %2
    mov ecx, %1
    mov ebx, MY_STDOUT
    mov eax, MY_SYS_WRITE
    int 0x80
%endmacro
​
%macro EASY_PRINT_STRING 1
    PRINT_STRING %1, %1_LEN 
%endmacro
​
section .data
    ANNOUNCE_STRING SOURCE, {"Charliechen is handsome", 0xA}
    BUFFER resb SOURCE_LEN
​
section .text
    global _start
​
_start:
    mov ecx, SOURCE_LEN
    mov edi, BUFFER
    mov esi, SOURCE
    cld     ; 设置我们的拷贝顺序是从左到右
    rep movsb
​
    PRINT_STRING BUFFER, SOURCE_LEN
​
    mov ebx, 0
    mov eax, 1
    int 0x80

lods, stos使用

我们的这个指令是用来存储和加载字符串的,操作方式是对之做每一个定长大小做操作。举个例子,我们想要对每一个字符加上一个2,变成一个面目全非的字符串,我们可以这样做:

; --------------------------------------------------
;   Program written in 10.21 2024
;   Author:             Charlie chen
;   Functionality:      usage of stosb, lodsb
; --------------------------------------------------
​
%macro ANNOUNCE_STRING 2
    %1 db %2
    %1_LEN equ $ - %1
%endmacro
​
; fast use of common value
%define MY_STDOUT       1
%define MY_SYS_WRITE    4
%define MY_STDIN        0
%define MY_SYS_READ     3
​
; print string in a simple way
%macro PRINT_STRING 2
    mov edx, %2
    mov ecx, %1
    mov ebx, MY_STDOUT
    mov eax, MY_SYS_WRITE
    int 0x80
%endmacro
​
%macro EASY_PRINT_STRING 1
    PRINT_STRING %1, %1_LEN 
%endmacro
​
section .data
    ANNOUNCE_STRING SOURCE, {"Charliechen is handsome", 0xA}
section .bss
    BUFFER resb SOURCE_LEN
​
section .text
    global _start
​
_start:
    mov ecx, SOURCE_LEN
    mov edi, BUFFER
    mov esi, SOURCE
do_add:
    lodsb
    add al, 0x2
    stosb
    loop do_add
    cld
    rep movsb
​
    PRINT_STRING BUFFER, SOURCE_LEN
​
    mov ebx, 0
    mov eax, 1
    int 0x80

cmpsb的使用

cmpsb是一个一个比特的比较,自动看ecx作为比较的次数。你看,这里是一个简单的比较键盘输入的两个字符串的程序

; --------------------------------------------------
;   Program written in 10.21 2024
;   Author:             Charlie chen
;   Functionality:      usage of cmpsb
; --------------------------------------------------
​
%macro ANNOUNCE_STRING 2
    %1 db %2
    %1_LEN equ $ - %1
%endmacro
​
; fast use of common value
%define MY_STDOUT       1
%define MY_SYS_WRITE    4
%define MY_STDIN        0
%define MY_SYS_READ     3
​
; print string in a simple way
%macro PRINT_STRING 2
    mov edx, %2
    mov ecx, %1
    mov ebx, MY_STDOUT
    mov eax, MY_SYS_WRITE
    int 0x80
%endmacro
​
%macro EASY_PRINT_STRING 1
    PRINT_STRING %1, %1_LEN 
%endmacro
​
%macro READ_FROM_CONSOLE 2
    mov edx, %2
    mov ecx, %1
    mov ebx, MY_STDIN
    mov eax, MY_SYS_READ
    int 0x80
%endmacro
​
section .data
    ANNOUNCE_STRING INPUT_SRC1, "Tell me your first input:> "
    ANNOUNCE_STRING INPUT_SRC2, "Tell me your second input:> "
    ANNOUNCE_STRING IS_EQUAL, {"The String is equal!",0xA}
    ANNOUNCE_STRING IS_NOT_EQUAL, {"The String is not equal!",0xA}
​
section .bss
    SOURCE1 resb 20
    SOURCE2 resb 20
​
​
section .text
    global _start
​
_start:
    EASY_PRINT_STRING INPUT_SRC1
    READ_FROM_CONSOLE SOURCE1, 20
    EASY_PRINT_STRING INPUT_SRC2
    READ_FROM_CONSOLE SOURCE2, 20
​
    mov esi, SOURCE1
    mov edi, SOURCE2
    mov ecx, 20
​
    cld
    repe cmpsb
    jecxz EQUAL
    jmp NOT_EQUAL
​
EQUAL:
    EASY_PRINT_STRING IS_EQUAL
    jmp EXIT
​
NOT_EQUAL:
    EASY_PRINT_STRING IS_NOT_EQUAL
    jmp EXIT
​
EXIT:
    mov ebx, 0
    mov eax, 1
    int 0x80

SCASB的使用

SCAS指令用于搜索字符串中的特定字符或一组字符。要搜索的数据项应该在AL(对于SCASB),AX(对于SCASW)或EAX(对于SCASD)寄存器中。要搜索的字符串应在内存中,并由ES:DI(或EDI)寄存器指向。

section .text
   global _start        ;must be declared for using gcc
        
_start:                 ;tell linker entry point
​
   mov ecx,len
   mov edi,my_string
   mov al , 'e'
   cld
   repne scasb
   je found ; when found
   ; If not not then the following code
        
   mov eax,4
   mov ebx,1
   mov ecx,msg_notfound
   mov edx,len_notfound
   int 80h
   jmp exit
        
found:
   mov eax,4
   mov ebx,1
   mov ecx,msg_found
   mov edx,len_found
   int 80h
        
exit:
   mov eax,1
   mov ebx,0
   int 80h
        
section .data
my_string db 'hello world', 0
len equ $-my_string  
​
msg_found db 'found!', 0xa
len_found equ $-msg_found
​
msg_notfound db 'not found!'
len_notfound equ $-msg_notfound   

标签:汇编,教程,STRING,mov,PRINT,寄存器,字符串,MY
From: https://blog.csdn.net/charlie114514191/article/details/143134013

相关文章

  • git安装-Tortoise git 安装汉化教程
    1.安装git2.安装git图形化工具Tortoisegit3.汉化Tortoisegit汉化安装包......
  • git安装-Tortoise git 安装汉化教程
    1.首先下载去官网下载如果下载比较慢的,链接自取https://pan.quark.cn/s/fcb9d0b39c7f2.安装git3.安装git图形化工具Tortoisegit4.汉化......
  • 最新激活Navicat 15教程,附Keygen Patch
    前言大家好,我是小徐啊。navicat是一款常用的数据库连接工具,但是它本身是需要收费的,很不方便。那么,有没有免费的方式呢?今天小徐就介绍下如何激活navicat的方式,永久激活。文末附获取方式。如何安装首先,双击navicat的安装包,开始安装,旁边的就是激活工具,待会再打开。然后,点击下一......
  • 图像去雨+图像去噪+图像去模糊一体化模型(图像处理-图像复原-代码+部署运行教程)
    本文主要讲述了一体化模型进行去噪、去雨、去模糊,也就是说,一个模型就可以完成上述三个任务。实现了良好的图像复原功能!先来看一下美女复原.jpg具体的完整代码文章底部推广获取:在图像恢复任务中,需要在恢复图像的过程中保持空间细节和高级上下文信息之间的复杂平衡。在......
  • Manim教程:第二章 输出界面的基本设置
    2.1页面的外观设计        在Manim中,图形的视觉表现和动画的美观性往往与背景颜色密切相关。用户可以轻松改变场景的背景颜色,这为动画赋予了更多的视觉特性和情感色彩。背景颜色的设置通常是动画创作的重要第一步,因为它可以影响观众的情绪和对内容的接受。比如,一个......
  • Altium Designer 入门基础教程(一)
     有将近一个半月没有更新过博客了,最近在整理AltiumDesigner 入门基础教程,希望喜欢本系列教程的小伙伴可以点点关注和订阅!下面我们开始进入AltiumDesigner课程的介绍。一、AltiumDesigner快捷键1.原理图快捷键: 2.PCB快捷键:  3.自定义快捷键(原理图、......
  • 星海智算:【镜像教程】MimicBrush:神奇画刷,一键搞定局部重绘!
    [MimicBrush 镜像教程 ]—— 欢迎使用星海智算——MimicBrush✦ 模型介绍 MimicBrush是由阿里巴巴、香港大学和蚂蚁集团联合研发的创新AI图像编辑工具。它允许用户通过简单操作,精准替换图片局部,轻松实现高质量的艺术修图。其特色功能包括先进的图像识别技术、自......
  • ORACLE 自定义函数,把字符串拆分为列/结果集
    使用REGEXP_SUBSTRSELECTREGEXP_SUBSTR(key,'[^,]+',1,ROWNUM)ASVALUEFROM(select'1,3,4,4'askeyfromdual)CONNECTBYROWNUM<=LENGTH(key)-LENGTH(REPLACE(key,',',''))+1;自定义函数:ODCIVARCHAR2LI......
  • Python之Matplotlib的基本使用教程
    1.安装pipinstallmatplotlib-ihttps://pypi.tuna.tsinghua.edu.cn/simple#在终端输入2.基本配置frommatplotlibimportpyplotasplt#让图片可以显示中文plt.rcParams['font.sans-serif']='SimHei'#让图片可以显示负号plt.rcParams['axes.unicode_minus'......
  • 通义灵码实践教程——单元测试
    通义灵码加持的单元测试实践本文首先讲述了什么是单元测试、单元测试的价值、一个好的单元测试所具备的原则,进而引入如何去编写一个好的单元测试,通义灵码是如何快速生成单元测试的。什么是单元测试?单元测试是一种软件测试方法,通过编写代码来验证应用程序中最小的可测试单元(如单......