0

I would like to make a copy of a string and store the copy in another variable. I want to do it the most basic way, cause I have just started learning Assembly. I have something like this:

section .data
        mystring db "string goes here", 10  ;string
        mystringlen equ $- mystring         ;length
        helper dw 0                         ;variable to help me in a loop

Now, I thought of a loop that will take each byte of the string and assign it to new string. I have this (I know it only changes initial string, but doesn't work either):

loopex:
    mov [mystring+helper], byte 'n' ;change byte of string to 'n'
    add helper, 1                   ;helper+=1
    cmp helper,mystringlen          ;compare helper with lenght of string 
    jl loopex                       

    ;when loop is done
    mov eax, 4
    mov ecx, mystring           ; print changed string
    mov edx, mystringlen        ; number of bytes to write

    ;after printing
    int 0x80                 ; perform system call
    mov eax, 1               ; sys_exit system call
    mov ebx, 0               ;exit status 0
    int 0x80

So I would need something like:

old_string = 'old_string'
new_string = ''
counter=0
while(counter!=len(old_string)):
  new_string[counter] = old_string[counter]
  counter+=1
print(new_string)
  • 1
    `new_string = ''` doesn't reserve any space to store into! You want something like `section .bss` / `new_string: resb mystringlen` and code for a memcpy loop. (If you want it statically allocated; otherwise reserve space on the stack or even call `malloc`). You also don't want static storage for `helper`; use registers for loop counters. – Peter Cordes May 29 '20 at 19:12
  • @PeterCordes Could you show me how to iterate over that reserved memory? – andrew_the_coder May 29 '20 at 19:35
  • 1
    Have you tried searching on Stack Overflow? [Copying to arrays in NASM](https://stackoverflow.com/q/56409664) shows how. – Peter Cordes May 29 '20 at 19:55
  • Post your answer as an answer, not an edit to the question. – Peter Cordes May 29 '20 at 20:35
  • Sorry for that. Thank you so much for your help and involvement - much appreciated! – andrew_the_coder May 29 '20 at 20:40

1 Answers1

2

The code after help I received:

section .data
        mystring db "This is the string we are looking for", 10
        mystringlen equ $- mystring

section .bss
    new_string: resb mystringlen

 section .text
    global _start

_start:
    mov ecx, 0
    mov esi, mystring
    mov edi, new_string

loopex:                 ; do {
    mov byte al, [esi]
    mov byte [edi], al
    inc esi
    inc edi
    inc ecx
    cmp ecx, mystringlen
    jl loopex           ; }while(++ecx < mystringlen)

;when loop is done
    mov eax, 4                   ; __NR_write (asm/unistd_32.h)
    mov ebx, 1                   ; fd = STDOUT_FILENO
    mov ecx, new_string          ; bytes to write
    mov edx, mystringlen         ; number of bytes to write
    int 0x80                  ; perform system call: write(1, new_string, mystringlen)

    ;after printing
    mov eax, 1           ; sys_exit system call number
    mov ebx, 0           ; exit status 0
    int 0x80
Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Thanks for writing up this example. I fixed a couple bugs (one real bugs, another in comment placement). Looping `mystringlen` times would be better done with `dec ecx` / `jnz loopex`, counting down from `mystringlen`. Also, the `byte` specifier in `mov byte al, [esi]` is redundant: AL is a register of known width. If anything you want to put it on the memory operand like you did in the other instruction, `byte [esi]`. So you can write `movzx eax, byte [esi]` to write the full EAX instead of merging a new AL into the low byte every iteration. – Peter Cordes May 29 '20 at 20:48