1

I'm new with assembly language and I'm having a problem with reversing a string.

For example:

original string: "ABCD"
after reversal: "DCBA"

I also want to put the reversed string into the same variable name that I used, and not using a new one. I thought about using a stack and here's a code that I wrote but I can't figure out where's my error:

IDEAL 
MODEL small
STACK 1000h

DATASEG

first db 'ABCD', 0

CODESEG

start:
    mov ax, @data
    mov ds, ax
    mov si, 0
    mov di, 0

loop_start:
    mov ax, [first+si]
    inc si
    test ax, ax
    jz done1ax

    push ax
    jmp loop_start

done1ax:
        pop ax
        mov [first+di], ax
        inc di
        cmp di, si
        JL done1ax

 mov dl, 10
 mov ah, 2
 int 21h
 ret

END start
Michael
  • 57,169
  • 9
  • 80
  • 125
gil
  • 2,388
  • 1
  • 21
  • 29
  • 3
    The characters in your string is one byte each. The `ax` register is a word register (two bytes). – Michael Oct 15 '15 at 09:17
  • right, but i read in tutorials that i cant define a string as 'DW' and on the other hand, i cant use stack with 'DB' variable. so how can i solve that issue? – gil Oct 15 '15 at 09:21
  • 1
    It's fine to `push` and `pop` `ax`, but the other operations like `mov` and `test` need to use an 8-bit register like `al`. – Michael Oct 15 '15 at 09:27
  • alright, i will try to fix it now. thanks for help – gil Oct 15 '15 at 09:28
  • Related: [assembly reverse a string](https://stackoverflow.com/q/38824670) has an efficient-ish loop that walks two pointers in opposite directions. – Peter Cordes May 18 '21 at 06:02

1 Answers1

0

Let me elaborate @Michael's comments:

IDEAL
MODEL small
STACK 1000h

DATASEG

first db 'ABCD', 0

CODESEG

start:
    mov ax, @data
    mov ds, ax
    xor si, si              ; mov si, 0
    xor di, di              ; mov di, 0

loop_start:
    mov al, [first+si]
    inc si
    test al, al
    jz done1ax

    push ax                 ; pushes implicit `AL`
    jmp loop_start

done1ax:
    pop ax                  ; pops `AL` and `AH`, `AH` isn't used
    mov [first+di], al
    inc di
    cmp di, si
    jb done1ax              ; jl is signed comparison: 8000h < 7FFFh

mov ah, 40h                 ; WriteFile
mov bx, 1                   ; STDOUT
mov cx, 4                   ; Number of bytes to write
mov dx, OFFSET first        ; Data to write
int 21h

mov ax, 4C00h               ; Return 0
int 21h

END start
rkhb
  • 14,159
  • 7
  • 32
  • 60
  • 1
    Even with the *AL versus AX* problem solved this program will crash because it does 1 `pop` too many! Solution: put `inc si` below `push ax` – Sep Roland Oct 18 '15 at 17:20