我想用“#”字符替换 dbyte 中的空格,并且 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
最佳答案
几个问题
push array call func ; ret 4
这是 16 位代码,因此数组被作为一个单词推送。 ret 4
应改为 ret 2
。请注意,您的数组实际上是一个以零结尾的字符串。
mov al, byte[bx+si]
如果您事先没有清除SI
,此操作将无法工作。
cmp al, 0 jz func
您正在使用您调用
的代码。您不应该像这样跳回调用者!
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
关于assembly - 如何替换Nasm程序中的特定字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56712860/