'How to get the beginning address of a string instead of the address of a whole string

SORRY if i make you confuse about the question, but i don't know a better to describe it

i'm trying to write a NASM program to reverse a string in place.

i have 3 function: strlen, readstring, and asm_main

readstring: read from user input and store it in reserved space "inputstring"

    push ebp        ; setup routine
    mov ebp, esp
    ;;;;;;;;;;;;;;;;;;;;;;;;;; 
    mov eax, message
    call print_string   ; print"please enter your string message"

    mov eax, 3  ; read
    mov ebx, 1  ; from standard input
    mov ecx,inputstring;  store at memory locaton inputstring
    mov edx, 100        ; 100 byte
    int 0x80

    mov eax, inputstring

   ;;;;;;;;;;;;;;;;;;;;;
    pop ebp
    ret

Later, i use another subprogram "strlen" to get the length of users' input

The problem is:

In my main program, i have two register hold the address of the beginning and the last char. so ecx holds begin, ebx holds last char

let's say i type "abcde",

so i have $ecx point to the beginning of the string, and $ebx point to the last char(which is e\n). My question is, when i swaping ecx and ebx, am i swapping the whole string(abcde) with the last char(e/n)?

or am i swaping the first char(a) with the last char(e/n)?

when i try to print out the content of each register in GDB.

ecx: abede/n

ebx: e/n

so i'm swaping the whole string with the last char, which is definitely not i want. So where did i do wrong??? can someone pls give me a hint?

Here is my code

%include "asm_io.inc"
segment .data
message db "Please enter your string message: ", 0xA,0
formatin db "%d", 0xA


segment .bss
   inputstring: resb 100

segment .text
    global asm_main
    extern printf
    extern scanf


**asm_main**:
    enter 0, 0
    pusha

    ;;;;;;;;;;;;;;;;;;;;;;;;
    call readstring
    mov ecx, eax    ; now ecx contains the begin address
    call strlen     ; when return, eax will hold the length

    push eax        ; we need eax in the loop

    ; use edi as temporary pointer
    ; use ebx to point to the last char

    mov ebx, 0    ;initialize ebx to 0
    add ebx, ecx  ; ebx = ecx now, ebx points to the beginning
    add ebx, eax  ; ebx = ecx + eax, now it points to then end
    sub ebx, 1    ; ebx = ecx +eax -1, now it points to the 
                  ; last char

while:
    cmp ebx, ecx   ; cmp end , begining
    jle exitWhile

    mov edi, [ebx]    ; temp = *end
    mov eax,[ecx]   ; *end = *begining
    mov [ebx], eax
    mov [ecx], edi    ; *beginning = temp

    inc ecx
    dec ebx

    jmp while

exitWhile:

    pop eax
    popa
    mov eax, 0
    leave           ; missing this line will cause segmentation 
                    ; fault, why?
    ret

**readstring**:
    push ebp        ; setup routine
    mov ebp, esp
    ;;;;;;;;;;;;;;;;;;;;;;;;;; 
    mov eax, message
    call print_string

    mov eax, 3  ; read
    mov ebx, 1  ; from standard input
    mov ecx,inputstring;  store at memory locaton inputstring
    mov edx, 100        ; 100 byte
    int 0x80

    mov eax, inputstring

   ;;;;;;;;;;;;;;;;;;;;;
    pop ebp
    ret


**strlen**:
    push ebp
    mov ebp, esp

    push esi
    ;;;;;;;;;;;;;;;;;;;;;
    mov esi, ecx    ; now esi contains the address of string
    mov edx, 0     ;  edx will be int i
loop:
    mov al, [esi]   ; al 
    cmp al, 0xA     ; check if al holds an ASCII new line
    je  exitLoop

    inc esi
    inc edx

    cmp esi, inputstring+100; see if esi is pointing past the end
                    ; of the 100 reserved byte

    jl loop


exitLoop:
    ;;;;;;;;;;;;;;;;;;;;
    mov eax, edx
    pop esi
    pop ebp
    ret


Solution 1:[1]

You are swapping four characters at a time since you are using 32-bit registers for the job. You swap "abcd" with "e\n??" (where ?? are the two bytes after your string). Use an 8-bit register for ASCII characters:

while:
  cmp ebx, ecx      ; cmp end , beginning
  jbe exitWhile     ; while (end > start) {

  mov al,[ebx]
  xchg al,[ecx]         ; extremely slow: atomic RMW + full memory barrier
  mov [ebx],al

  inc ecx
  dec ebx

  jmp while        ; }

exitWhile:

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Peter Cordes