首页 > 解决方案 > 如何替换 Nasm 程序中的特定字符

问题描述

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

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

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

标签: assemblynasmx86-16

解决方案


几个问题

push array
call func
;
ret 4

这是 16 位代码,因此数组作为一个字被推送。ret 4应该ret 2是。请注意,您的数组实际上是一个以零结尾的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

推荐阅读