如何在Nasm程序中替换特定字符

时间:2019-06-22 05:30:37

标签: assembly nasm x86-16

我想用'#'字符替换dbyte中的空格,并且 db应该通过堆栈传递给过程。

我已经编写了下一个代码片段,并且替换正常,但我不明白如何正确地将db传递给过程func

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 个答案:

答案 0 :(得分:2)

几个问题

push array
call func
;
ret 4

这是16位代码,因此 array 被压为一个单词。 ret 4应该改为ret 2。请注意,您的 array 实际上是一个以零结尾的 string

mov al, byte[bx+si]

如果您事先没有清除SI,此操作将无效。

cmp al, 0
jz func

您使用的是call编辑过的代码。您不应该像这样跳回呼叫者!

cmp al , ' '
jnz loop

此跳转到顶部错过了SI上的增量。

mov [bp + 4], bx

这是多余的,因为未修改参数。此外,您还是要丢弃它。

mov bp, sp 
mov bx, [bp]

这有用吗?它只是加载随后程序终止的返回地址。

ret

这种终止程序的方式取决于正确的堆栈。并非总是如此!最好通过以下方式终止DOS程序:

mov ax, 4C00h
int 21h

放在一起

 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