Mark green
Mark green

Reputation: 43

assembly switch between 2 chars in string

i am trying to flip between 2 chars in a string, so i buily function that get pointer to the 2 chars and then switch them. the function work fine with regular assmbly chars, but when i pass the parameter as char from string it start to get crazy and flip chars from other places. for example, i got this string:

string db 'd', 'a', 'b', 'e', 'c', 0Dh, 0Ah, '$'

and i want to flip between the 'd' and the 'e'. so i do this for moving them to the function:

lea bx, string
lea ax, [bx] ;i use lea to get the pointer not the char
push ax

lea ax, [bx + 3]
push ax

; i know push 2 parameters.

but from some reason after the switch the string change to this:

string db 'e', 'c', 'b', 'd', 'a', 0Dh, 0Ah, '$'

so it du succes to swap between the 2 chars, but from some reason the function did the same for the char comming after them:

[bx + 1] and [bx + 4]. why is that? this is my code so far: (print = print new line, print_ax_str this is function that print the ptr string inside ax. all that from the inc file)

org 100h

jmp main

string db 'd', 'a', 'b', 'e', 'c', 0Dh, 0Ah, '$'
length dw 3

main:
    xor ax, ax
    xor bx, bx
    xor dx, dx
    xor cx, cx
    xor si, si
    xor bp, bp

    lea bx, string
    mov ax, bx
    print "Before string: "
    call print_ax_str

    lea ax, [bx]
    push ax

    lea ax, [bx + 3]
    push ax

    call swap ;swap the chars.

    lea ax, string
    print "After string: "
    call print_ax_str        
    jmp end        
swap:
    push cx
    push bx
    push dx
    push ax
    push bp


    mov bp, sp

    mov ax, [bp + 12]; ax = ptr char 2

    mov cx, [bp + 14]; cx = ptr char 1

    mov bx, ax
    mov ax, [bx] ;ax = char 2

    mov bx, cx
    mov dx, [bx] ;dx = char 1
    mov [bx], ax ;char 1 = char 2 


    mov bx, [bp + 12]
    mov [bx], dx ;char 2 = char 1 
    mov ax, [bx]

    mov sp, bp
    pop bp
    pop ax
    pop dx
    pop bx
    pop cx
    retn 4


end:
    mov ah, 0
    int 16h
    ret

include prints.inc

Upvotes: 2

Views: 1970

Answers (1)

Fifoernik
Fifoernik

Reputation: 9899

mov ax, [bx] ;ax = char 2
mov dx, [bx] ;dx = char 1
mov [bx], ax ;char 1 = char 2 
mov [bx], dx ;char 2 = char 1

The string that you're processing is composed of bytes, but your program swaps words. That's the reason why results are off.
As a quick fix write:

mov al, [bx] ;AL = char 2
mov dl, [bx] ;DL = char 1
mov [bx], al ;char 1 = char 2 
mov [bx], dl ;char 2 = char 1

If you're interested in writing a better program, then re-write the SWAP procedure.

  • Setup BP before pushing the additional registers so that addressing the parameters can use the familiar offsets like [bp+4] for the 1st parameter and [bp+6] for the 2nd parameter.
  • Move the parameters directly to address registers (BX, SI, DI) so you can avoid moving things around a lot.

New version:

swap:
 push bp
 mov  bp, sp

 push ax
 push dx
 push si
 push di

 mov  di, [bp + 4]  ; ptr char 2
 mov  si, [bp + 6]  ; ptr char 1

 mov  dl, [di]      ; DL = char 2
 mov  al, [si]      ; AL = char 1

 mov  [si], dl      ; char 1 = char 2 
 mov  [di], al      ; char 2 = char 1 

 pop  di
 pop  si
 pop  dx
 pop  ax

 pop  bp
 retn 4

mov ax, [bx]
mov sp, bp
pop bp
pop ax

A couple of remarks on this part of the code:

  1. Can you see that the mov ax,[bx] instruction followed by a pop ax instruction is useless?
  2. You don't have to write the mov sp, bp instruction because the stackpointer is still pointing at the pushed registers.

Upvotes: 3

Related Questions