How to replace specific character in Nasm procedure

Viewed 252

I want to replace white-spaces in dbyte with '#' character, and db should be passed to the procedure by stack.

I've written next snippet and replacing is working, but I can't understand how to pass db to procedure func properly.

org 0x100 
    push array
    call func
    mov bp, sp 
    mov bx, [bp]
    ret 

loop:
    mov al, byte[bx+si]
    cmp al, 0
     jz func
    cmp al , ' '
     jnz loop
    mov byte[bx+si], '#'
    inc si
    jmp loop
    ret

func:  
    push bp  
    mov bp, sp  
    mov bx, [bp + 4]    
    call loop
    mov [bp + 4], bx
    pop bp  
    ret 4 

array db "a b c", 0
1 Answers

Several problems

push array
call func
;
ret 4

This is 16-bit code and so array is pushed as a word. The ret 4 should be ret 2 instead. Note that your array is actually a zero-terminated string.

mov al, byte[bx+si]

This can not work if you didn't clear SI beforehand.

cmp al, 0
jz func

You are in code that you've called. You shouldn't jump back to the caller like this!

cmp al , ' '
jnz loop

This jump to the top misses the increment on SI.

mov [bp + 4], bx

This is redundant since the argument wasn't modified. Moreover you're going to discard it anyway.

mov bp, sp 
mov bx, [bp]

Is this useful? It just loads the return address for the program termination that follows.

ret

This way of terminating the program depends on a correct stack. That will not always be the case! DOS programs are better terminated through:

mov ax, 4C00h
int 21h

Putting it together

 org  256

 push MyString
 call Func
 mov  bp, sp 
 mov  bx, [bp]
 mov  ax, 4C00h  ;Program termination
 int  21h

Loop:
 mov  al, byte[bx+si]
 cmp  al, 0
 je   EndOfLoop
 cmp  al, ' '
 jne  NotASpace
 mov  byte[bx+si], '#'
NotASpace:
 inc  si
 jmp  Loop
EndOfLoop:
 ret

;Clobbers AL, BX, SI
Func:  
 push bp  
 mov  bp, sp  
 mov  bx, [bp + 4]
 xor  si, si
 call Loop
 pop  bp  
 ret  2

MyString db "a b c", 0
Related