前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >汇编学习(10) 字符串

汇编学习(10) 字符串

作者头像
一只小虾米
发布2022-12-19 08:34:02
3910
发布2022-12-19 08:34:02
举报
文章被收录于专栏:Android点滴分享Android点滴分享

本篇介绍

本篇介绍下汇编中的字符串。

字符串

C语言中定义字符串是会以"\0"结束,汇编中不会这样,只要是一块连续的内存,都可以认为是字符串。 下面是一段操作字符串的代码:

代码语言:javascript
复制
; move_strings.asm
%macro prnt 2
    mov     rax, 1      ; 1 = write     
    mov     rdi, 1      ; 1 = to stdout         
    mov     rsi, %1                 
    mov     rdx, %2                     
    syscall
    mov rax, 1
    mov rdi, 1
    mov rsi, NL
    mov rdx, 1
    syscall

%endmacro

section .data                           
    length  equ 95
    NL db 0xa
    string1 db "my_string of ASCII:"
    string2 db 10,"my_string of zeros:"
    string3 db 10,"my_string of ones:"
    string4 db 10,"again my_string of ASCII:"
    string5 db 10,"copy my_string to other_string:"
    string6 db 10,"reverse copy my_string to other_string:"
section .bss
        my_string  resb length
    other_string resb length

section .text                           
    global main                     
main:
push    rbp
mov     rbp, rsp
;-----------------------------------------------------------------------
;fill the string with printable ascii characters
        prnt string1,18
        mov rax,32
        mov rdi,my_string
        mov rcx, length
str_loop1:  mov byte[rdi], al       ; the simple method
        inc rdi
            inc al
        loop str_loop1
        prnt my_string,length
;-----------------------------------------------------------------------
;fill the string with ascii 0's
        prnt string2,20
        mov rax,48
        mov rdi,my_string
        mov rcx, length
str_loop2:  stosb               ; no inc rdi needed anymore
        loop str_loop2
        prnt my_string,length
;-----------------------------------------------------------------------
;fill the string with ascii 1's
        prnt string3,19
        mov rax, 49
        mov rdi,my_string
        mov rcx, length
            rep stosb           ; no inc rdi and no loop needed anymore
        prnt my_string,length
;-----------------------------------------------------------------------
;fill the string again with printable ascii characters
        prnt string4,26
        mov rax,32
        mov rdi,my_string
        mov rcx, length
str_loop3:  mov byte[rdi], al       ; the simple method
        inc rdi
        inc al
        loop str_loop3
        prnt my_string,length
;-----------------------------------------------------------------------
;copy my_string to other_string 
        prnt string5,32
        mov rsi,my_string           ;rsi source
        mov rdi,other_string        ;rdi destination
        mov rcx, length
        rep movsb
        prnt other_string,length
;-----------------------------------------------------------------------
;reverse copy my_string to other_string 
        prnt string6,40
        mov rax, 48         ;clear other_string
        mov rdi,other_string
        mov rcx, length
            rep stosb           
        lea rsi,[my_string+length-4]
        lea rdi,[other_string+length]
        mov rcx, 27         ;copy only ten characters
        std                 ;std sets DF, cld clears DF
        rep movsb
        prnt other_string,length
leave
ret             
结果如下:
ngs$ ./move_strings 
my_string of ASCII
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

my_string of zeros:
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

my_string of ones:
11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111

again my_string of ASCII:
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

copy my_string to other_string:
 !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~

reverse copy my_string to other_string:
000000000000000000000000000000000000000000000000000000000000000000000abcdefghijklmnopqrstuvwxyz

stosb 用于循环赋值,每次一个字节,rcx中存放次数,rax存放源,rdi存放目的地址,每次循环rdi会自动增加1。 movsb 也是循环赋值,每次一个字节,rcx中存放次数,rsi存放源,rdi存放目的地址,每次rsi,rdi会增加1,如果设置DF标记,会每次减1。 再看一个比较字符串的例子:

代码语言:javascript
复制
; strings.asm
extern  printf                                      
section .data                           
    string1     db "This is the 1st string.",10,0
    string2     db "This is the 2nd string.",10,0
    strlen2     equ $-string2-2
    string21    db "Comparing strings: The strings do not differ.",10,0
    string22    db "Comparing strings: The strings differ, "
            db "starting at position: %d.",10,0
    string3     db "The quick brown fox jumps over the lazy dog.",0
    strlen3     equ $-string3-2
    string33    db "Now look at this string: %s",10,0
    string4     db "z",0
    string44    db "The character '%s' was found at position: %d.",10,0
    string45    db "The character '%s' was not found.",10,0
    string46    db "Scanning for the character '%s'.",10,0
section .bss
section .text                           
    global main                     
main:
        push rbp
        mov     rbp,rsp
; print the 2 strings
    xor rax,rax
    mov rdi, string1
    call printf
    mov rdi, string2
    call printf   
; compare 2 strings ------------------------------------------------------------------------------
    lea rdi,[string1]
    lea rsi,[string2]
    mov rdx, strlen2
    call compare1
    cmp rax,0
    jnz not_equal1
;strings are equal, print
    mov rdi, string21
    call printf
    jmp otherversion
;strings are not equal, print
not_equal1:
    mov rdi, string22
    mov rsi, rax
    xor rax,rax
    call printf 
; compare 2 strings, other verstion -----------------------------------------------------
otherversion:
    lea rdi,[string1]
    lea rsi,[string2]
    mov rdx, strlen2
    call compare2
    cmp rax,0
    jnz not_equal2
;strings are equal, print
    mov rdi, string21
    call printf
    jmp scanning
;strings are not equal, print
not_equal2:
    mov rdi, string22
    mov rsi, rax
    xor rax,rax
    call printf 
; scan for a character in a string ---------------------------------------------------------------
; first print the string
    mov rdi,string33
    mov rsi,string3
    xor rax,rax
    call printf
; then print the search argument, can only be 1 character
    mov rdi,string46
    mov rsi,string4
    xor rax,rax
    call printf
scanning:
    lea rdi,[string3]   ;   string
    lea rsi,[string4]   ;   search argument
    mov rdx, strlen3
    call cscan
    cmp rax,0
    jz char_not_found
;character found, print
    mov rdi,string44
    mov rsi,string4
    mov rdx,rax
    xor rax,rax
    call printf
    jmp exit
;character not found, print
char_not_found: 
    mov rdi,string45
    mov rsi,string4
    xor rax,rax
    call printf
exit:
leave
ret

; FUNCTIONS ======================================================================================

; function compare 2 strings ---------------------------------------------------------------------
compare1:   mov rcx, rdx
        cld
cmpr:   cmpsb
        jne notequal
        loop cmpr
        xor rax,rax
        ret
notequal:   mov rax, strlen2
        dec rcx     ;compute position
        sub rax,rcx ;compute position
        ret
        xor rax,rax
        ret
;------------------------------------------------------------------------------
; function compare 2 strings ---------------------------------------------------------------------
compare2:   mov rcx, rdx
        cld
        repe cmpsb
        je equal2
        mov rax, strlen2
        sub rax,rcx ;compute position
        ret
equal2: xor rax,rax
        ret
;------------------------------------------------------------------------------
;function scan a string for a character
cscan:  mov rcx, rdx
        lodsb
        cld
        repne scasb
        jne char_notfound
        mov rax, strlen3
        sub rax,rcx ;compute position
        ret
char_notfound:  xor rax,rax
        ret
结果如下:           
./strings 
This is the 1st string.
This is the 2nd string.
Comparing strings: The strings differ, starting at position: 13.
Comparing strings: The strings differ, starting at position: 13.
Now look at this string: The quick brown fox jumps over the lazy dog.
Scanning for the character 'z'.
The character 'z' was found at position: 38

comsb用来比较rsi,rdi指向需要比较的字符串地址,结果会存放到ZF标记中,如果是1表示相等,0则反之, 需要借助loop 才能比较ecx指定的长度。 repe(repeat while equal), repne(repeat while not equal),借助comsb,scasb就可以查找字符串了。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2022-12-18,如有侵权请联系 cloudcommunity@tencent.com 删除

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

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本篇介绍
  • 字符串
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档