我想用'#'字符替换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
答案 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