0

Im trying to swap the values of two similarly long strings with each other. However, the solution I have been trying to use is not working. It involves the use of a local variable to store the address of the other string and a loop to copy the contents of the other string to another through its memory address and by using the length of the string to iterate through it

global _start
global get_strlen
global get_vowel

section .data
NULL equ 0
SYS_EXIT equ 60
string1 db 'hello everyone', NULL
strlen dq 0

section .bss
string2 resb 20

section .text
_start:
mov rdi, string1
mov rsi, strlen
call get_strlen

mov rsi, string1
mov rdi, string2
mov rdx, qword[strlen]
mov rcx, qword[strlen]
call get_vowel

exit_here:
mov rax, SYS_EXIT
xor rdi, rdi
syscall


get_strlen:
len_loop:
    mov al, byte[rdi]
    cmp al, NULL
    je return

    inc rdi
    inc byte[rsi]
    jmp len_loop
return:
    ret

get_vowel:
push rbp
mov rbp, rsp
sub rsp, 8

mov rcx, rcx
mov rsi, rsi
mov rdi, rdi
cld
str_loop:

lodsb
stosb

cmp al, 'a'
je vowel_a
cmp al, 'e'
je vowel_e
cmp al, 'i'
je vowel_i
cmp al, 'o'
je vowel_o
cmp al, 'u'
je vowel_u
loop str_loop

mov byte[rdi], NULL
mov al, 0
jmp str_swap

vowel_a:
    dec rdi
    mov byte[rdi], '@'
    inc rdi
    jmp str_loop

vowel_e:
    dec rdi
    mov byte[rdi], '3'
    inc rdi
    jmp str_loop

vowel_i:
    dec rdi
    mov byte[rdi], '1'
    inc rdi
    jmp str_loop

vowel_o:
    dec rdi
    mov byte[rdi], '0'
    inc rdi
    jmp str_loop

vowel_u:
    dec rdi
    mov byte[rdi], 'U'
    inc rdi
    jmp str_loop

str_swap:                 ;swaps address of string1 and string2
    mov r10, rdi
    mov qword[rbp-8], r10
    mov r10, rsi
    mov rdi, r10
    mov r10, qword[rbp-8]
    mov rsi, r10
    jmp str_copy

str_copy:                  ;swap string1 and string2 values
mov rcx, rdx
mov rsi, rsi
mov rdi, rdi
cld

loop1:
    movsb
    loop loop1
    mov byte[rdi], NULL

add rsp, 8
pop rbp
ret

the ending always results in the value of string2 to be the manipulated string value and the value of string1 remains the same throughout

honj - t
  • 87
  • 8
  • What does the `get_vowel` stuff have to do with anything? The text of your question didn't mention anything about conditional behaviour, just swapping memory, so this [mcve] isn't minimal. – Peter Cordes May 15 '21 at 00:46
  • If you're talking about your `movsb` loop, that's a one-way copy. (And use `rep movsb`, that's much more efficient than putting `movsb` in a loop.) If you want to swap without needing a 3rd buffer as long as the strings, load bytes from each string into registers, then store to the other. – Peter Cordes May 15 '21 at 00:49
  • @PeterCordes Hi, I am sorry about the lengthy post. I am new to the site so I was not wary about the etiquette regarding it (but even then, I should have expected that code posted should just be snippets and straight to the point). In any case, may I ask something about the movsb loop? It happens to work if I separate it from the function (just the copying; I'll think about the swap later). – honj - t May 15 '21 at 01:24
  • 1
    Yeah, `movsb` is memcpy(rdi, rsi, 1). It's a correct (inefficient) one-way copy, that's *why* it's not a correct swap of the string data, and that's what you said the problem was. `rep movsb` is memcpy(rdi, rsi, rcx) (with [optimized microcode](https://stackoverflow.com/questions/33902068/what-setup-does-rep-do) to actually copy in larger chunks like 16 or 32 bytes at a time, unlike if you use the `loop` instruction to manually repeat `movsb`, which itself is slow.) – Peter Cordes May 15 '21 at 01:27

0 Answers0